Path作為Android中一種相對復雜的繪圖方式,官方文檔中的有些解釋并不是很好理解,這里作一個相對全面一些的總結,供日后查看,也分享給大家,共同進步。
1.基本繪圖方法
- addArc(RectF oval, float startAngle, float sweepAngle)
繪制弧線,配合Paint的Style可以實現不同的填充效果 - addCircle(float x, float y, float radius, Path.Direction dir)
繪制圓形,其中第dir
參數用來指定繪制時是順時針還是逆時針 - addOval(RectF oval, Path.Direction dir)
繪制橢圓形,其中?oval
作為橢圓的外切矩形區域 - addRect(RectF rect, Path.Direction dir)
繪制矩形 - addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
繪制圓角矩形 - lineTo(float x, float y)
繪制直線 - addPath(Path src)
添加一個新的Path到當前Path - arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
與addArc
方法相似,但也有區別,下文細述。 - quadTo(float x1, float y1, float x2, float y2)
繪制二次貝塞爾曲線
,其中 (x1,y1)為控制點,(x2,y2)為終點 - cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
繪制三次貝塞爾曲線
,其中(x1,y1),(x2,y2)為控制點,(x3,y3)為終點
2.rXXX方法
上面的lineTo,MoveTo,QuadTo,CubicTo方法都有與之對應的rXXX
方法:
- rLineTo(float dx, float dy)
- rMoveTo(float dx, float dy)
- rQuadTo(float dx1, float dy1, float dx2, float dy2)
- rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
這些方法與之對應的原方法相比,惟一的區別在于:r方法是基于當前繪制開始點的offest,比如當前paint位于 (100,100)處,則使用rLineTo(100,100)
方法繪制出來的直線是從(100,100)到(200,200)的一條直接,由此可見rXXX
方法方便用來基于之前的繪制作連續繪制。
3.Path.op方法
1 | //原型 |
此方法用于對兩個Path對象做相應的運算組合(combine),具體的說是根據不同的op
參數及path2參數來影響path1對象,有點類似于數學上的集合運算。請看下面的例子:
1 | Path path1 = new Path(); |
效果如下:
通過不斷修改path1.op的第二個參數依次可以得到如下效果:
Path.Op.INTERSECT
效果:Path.Op.UNION
效果:Path.Op.REVERSE_DIFFERENCE
效果:Path.Op.XOR
效果:
總結:
- Path.Op.DIFFERENCE 減去path1中path1與path2都存在的部分;
path1 = (path1 - path1 ∩ path2) - Path.Op.INTERSECT 保留path1與path2共同的部分;
path1 = path1 ∩ path2 - Path.Op.UNION 取path1與path2的并集;
path1 = path1 ∪ path2 - Path.Op.REVERSE_DIFFERENCE 與DIFFERENCE剛好相反;
path1 = path2 - (path1 ∩ path2) - Path.Op.XOR 與INTERSECT剛好相反;
path1 = (path1 ∪ path2) - (path1 ∩ path2)
4.setFillType
設置path的填充模式.網上關于path的FillType的介紹很少,實際上在官方ApiDemos
里就有個很好的例子:
1 | /** |
效果如下:
(上面的例子在官方ApiDemo的基礎上做了適當的修改)
總結:
所謂填充指的就是填充內部,setFillType
就是用來界定哪里算內部的算法。在計算機圖形學中界定一個點是不是在多邊形內部有兩種算法:
- 非零環繞數規則(Nonzero-rule)
- 奇偶規則(Even–odd rule)
關于這兩種算法這里不作詳細介紹,具體可以參考上面的維基鏈接,或者這篇中文資料(注意看評論區)
5.易混淆的方法
1. addArc 與 arcTo
前者指定在某處畫一條弧線,僅此而已,不會受當前paint的位置所影響。而arcTo方法有兩種形式:
- arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
-
arcTo(RectF oval, float startAngle, float sweepAngle)
對于第一種形式的方法,若forceMoveTo參數為false,則與第二種形式的方法沒區別,繪制成的最終圖形會受到落筆點的影響;
若forceMoveTo參數值為true,則繪制效果與addArc
方法沒有區別。
1 | //代碼1 |
代碼1效果如下圖:
1 | //代碼2 |
代碼2效果如下圖:
若將代碼2中的arcTo方法的參數修改為true則繪制的效果與代碼1相同。
2. reset 與 rewind
reset
清除path上的內容,重置path到 path = new Path()的初始狀態。rewind
清除path上的內容,但會保留path上相關的數據結構,以高效的復用。
Detail
其它方法
- moveTo(float x,float y)
移動畫筆到 (x,y) 處 - offset(float dx, float dy)
平移當前path,在此path上繪制的任何圖形都會受到影響 - close()
閉合當前路徑 (系統會自動從起點到終點繪制一條直線,使當前路徑閉合) - reset()
重置path,但不會重置fill-type
設置 - rewind()
重置path,但會保留內部數據結構 - set(Path src)
設置新的Path到當前對象 - setLastPoint(float x,float y)
設置當前path的終點 - transform(Matrix matrix)
矩陣變換