自定義View-第九步:Path的部分相關(guān)方法

前言

根據(jù)Gcssloop所學習的自定義View整理與筆記。

一.填充模式

填充模式相關(guān)方法

方法 作用
setFillType 設置填充規(guī)則
getFillType 獲取當前填充規(guī)則
isInverseFillType 判斷是否是反向(INVERSE)規(guī)則
toggleInverseFillType 切換填充規(guī)則(即原有規(guī)則與反向規(guī)則之間相互切換)

填充規(guī)則有四種

模式 簡介
EVEN_ODD 奇偶規(guī)則
INVERSE_EVEN_ODD 反奇偶規(guī)則
WINDING 非零環(huán)繞數(shù)規(guī)則
INVERSE_WINDING 反非零環(huán)繞數(shù)規(guī)則

** 1. 我們首先了解一下什么是奇偶規(guī)則。**
奇偶規(guī)則:如果是奇數(shù),那么要被填充,如果是偶數(shù)則不填充。那么,怎么判斷奇數(shù)還是偶數(shù)呢?
從任意位置p作一條射線, 若與該射線相交的圖形邊的數(shù)目為奇數(shù),需要被填充,否則是偶數(shù),不被填充。


引用自http://www.gcssloop.com/customview/Path_Over

可以看出,
P1: 從P1發(fā)出一條射線,發(fā)現(xiàn)圖形與該射線相交邊數(shù)為0,偶數(shù),不被填充。
P2: 從P2發(fā)出一條射線,發(fā)現(xiàn)圖形與該射線相交邊數(shù)為1,奇數(shù),被填充。
P3: 從P3發(fā)出一條射線,發(fā)現(xiàn)圖形與該射線相交邊數(shù)為2,偶數(shù),不被填充。

注意:奇偶規(guī)則與方向無關(guān)。


奇偶規(guī)則填充

自然,反奇偶規(guī)則剛好與奇偶規(guī)則是相反的,不在贅述咯!
** 2. 非零環(huán)繞數(shù)規(guī)則揭秘**
假如一個點被從左到右跨過,計數(shù)器+1,從右到左跨過,計數(shù)器-1,最后,如果結(jié)果是0,那么不填充,如果是非零,那么填充。
注意:非零環(huán)繞數(shù)規(guī)則與方向有關(guān)哦,Path中任何線段都是有方向性的,這也是使用非零環(huán)繞數(shù)規(guī)則的基礎(chǔ)。

非零環(huán)繞數(shù)規(guī)則

P1: 從P1點發(fā)出一條射線,沿射線防線移動,并沒有與邊相交點部分,環(huán)繞數(shù)為0,故不填充。

P2: 從P2點發(fā)出一條射線,沿射線方向移動,與圖形點左側(cè)邊相交,該邊從左到右穿過穿過射線,環(huán)繞數(shù)-1,最終環(huán)繞數(shù)為-1,故填充。
P3: 從P3點發(fā)出一條射線,沿射線方向移動,在第一個交點處,底邊從右到左穿過射線,環(huán)繞數(shù)+1,在第二個交點處,右側(cè)邊從左到右穿過射線,環(huán)繞數(shù)-1,最終環(huán)繞數(shù)為0,故不填充。

注意方向哦

自然,反非零環(huán)繞數(shù)規(guī)則是與非零環(huán)繞數(shù)規(guī)則是相反的,也不在贅述咯!

接下來,就以非零環(huán)繞規(guī)則舉個demo吧

       paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLACK);
        canvas.translate(300, 300);
        Path path = new Path();
        //內(nèi)外同向
        path.addRect(-200, -200, 200, 200, Path.Direction.CCW);
//        path.addRect(-100, -100, 100, 100, Path.Direction.CCW);
        //內(nèi)外不同向
        path.addRect(-100, -100, 100, 100, Path.Direction.CW);

        //非零環(huán)繞數(shù)規(guī)則
        path.setFillType(Path.FillType.WINDING);
        canvas.drawPath(path, paint);

效果圖


內(nèi)外同向
內(nèi)外反向

二.布爾操作(API19)

1.Path的布爾運算邏輯

名稱 類比 說明 示意圖
DIFFREENCE 差集 Path1中減去Path2后剩下的部分
REVERSE_DIFFERENCE 差集 Path2中減去Path1后剩下的部分
INTERSECT 交集 Path1與Path2相交的部分
UNION 并集 包含全部Path1和Path2
XOR 異或 包含Path1和Path2但不包含兩者相交的部分

2.布爾運算的方法

boolean op (Path path, Path.Op op)
boolean op (Path path1, Path path2, Path.Op op)

詳細說明的話,咱們得舉個小小例子

// 對 path1 和 path2 執(zhí)行布爾運算,運算方式由第二個參數(shù)指定,運算結(jié)果存入到path1中。
path1.op(path2, Path.Op.DIFFERENCE);
// 對 path1 和 path2 執(zhí)行布爾運算,運算方式由第三個參數(shù)指定,運算結(jié)果存入到path3中。
path3.op(path1, path2, Path.Op.DIFFERENCE)

來個太極demo:

        canvas.drawColor(Color.YELLOW);
        paint.setStyle(Paint.Style.FILL);
        canvas.translate(300, 300);
        //繪制一個白色的圓
        paint.setColor(Color.WHITE);
        canvas.drawCircle(0,0,200,paint);
       //繪制太極
        paint.setColor(Color.BLACK);
        Path path1 = new Path();
        Path path2 = new Path();
        Path path3 = new Path();
        Path path4 = new Path();
        path1.addCircle(0, 0, 200, Path.Direction.CW);
        path2.addRect(0, -200, 200, 200, Path.Direction.CW);
        path3.addCircle(0, -100, 100, Path.Direction.CW);
        path4.addCircle(0, 100, 100, Path.Direction.CW);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //path1減去path2,將結(jié)果存入path1
            path1.op(path2, Path.Op.DIFFERENCE);
            //包含全部path1和path3,將結(jié)果存入path1
            path1.op(path3, Path.Op.UNION);
            //path1減去path4,將結(jié)果存入path1
            path1.op(path4, Path.Op.DIFFERENCE);
        }
        //繪制path1
        canvas.drawPath(path1, paint);
太極demo

小記:API<19的,要使用Region的op,Region我們將會放在自定義View-第十二步:Region講解。

三.計算邊界

void computeBounds (RectF bounds, boolean exact)
  • bounds:測試結(jié)果會放入這個矩形
  • exact :是否精確測量,這個參數(shù)作用目前已被廢棄,寫true即可
//----------
//上個demo的代碼
//在下邊加上如下代碼,測量path1的邊界
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.RED);
        RectF rect = new RectF();
        path1.computeBounds(rect, true);
        canvas.drawRect(rect, paint);
邊界測量效果圖

四.重置路徑reset和rewind

|方法| 是否保留FillType設置| 是否保留原有數(shù)據(jù)結(jié)構(gòu)|
|--------|--------|------|
|reset| 是 |否|
|rewind |否| 是|
這個兩個方法應該何時選擇呢?
選擇權(quán)重: FillType > 數(shù)據(jù)結(jié)構(gòu)
因為“FillType”影響的是顯示效果,而“數(shù)據(jù)結(jié)構(gòu)”影響的是重建速度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容