目錄
- 一、xxxTo方法
- 1、lineTo(float x, float y)
- 2、moveTo(float x, float y)
- 3、arcTo
- 3.1、arcTo(RectF oval, float startAngle, float sweepAngle)
- 3.2、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)
- 3.3、arcTo(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean forceMoveTo)
- 4、quadTo(float x1, float y1, float x2, float y2)
- 5、cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
- 二、rXxxTo方法
- 三、addXxx方法
- 1、addArc(RectF oval, float startAngle, float sweepAngle)
- 2、addCircle(float x, float y, float radius, Direction dir)
- 3、addOval(RectF oval, Direction dir)
- 4、addRect(RectF rect, Direction dir)
- 5、addRoundRect
- 5.1、addRoundRect(RectF rect, float rx, float ry, Direction dir)
- 5.2、addRoundRect(RectF rect, float[] radii, Direction dir)
- 6、addPath(Path src)
- 6.1、addPath(Path src, float dx, float dy)
- 6.2、addPath(Path src, Matrix matrix)
- 四、填充模式
- 五、其他方法
- 1、op(Path path, Op op) 布爾運算
- 1.1、DIFFERENCE(差集)
- 1.2、REVERSE_DIFFERENCE(差集)
- 1.3、INTERSECT(交集)
- 1.4、UNION(并集)
- 1.5、XOR(異或)
- 2、setLastPoint(float dx, float dy)
一、xxxTo方法
Path
類中提供了一套xxxTo
方法,其作用是從起點到終點移動path畫筆并繪制線(moveTo方法只移動path畫筆不繪制線),線有直線和曲線
。
方法匯總如下表所示:
方法名 | 參數解析 |
---|---|
lineTo(float x, float y) | 繪制直線,x:終點x坐標值,y:終點y坐標值 |
moveTo(float x, float y) | 移動畫筆,x:終點x坐標值,y:終點y坐標值 |
arcTo(RectF oval, float startAngle, float sweepAngle) | 繪制圓弧,oval:圓弧矩形區域,startAngle:起始角度,sweepAngle:圓弧旋轉的角度 |
arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo) | 繪制圓弧,oval:圓弧矩形區域,startAngle:起始角度,sweepAngle:圓弧旋轉的角度,forceMoveTo:是否在繪制圓弧前移動(moveTo)path畫筆位置 |
arcTo(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean forceMoveTo) | 繪制圓弧,left、top、right、bottom組成圓弧矩形區域,startAngle:起始角度,sweepAngle:圓弧旋轉的角度,forceMoveTo:是否在繪制圓弧前移動(moveTo)path畫筆位置 |
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) | 繪制三階貝塞爾曲線,其中控制點1坐標為(x1,y1),控制點2坐標為(x2,y2),終點坐標為(x3,y3) |
1、lineTo(float x, float y)
繪制直線:從當前畫筆位置出發,連接終點(x,y)。
示例如下:
path.lineTo(300,300);
canvas.drawPath(path,paint);
2、moveTo(float x, float y)
移動畫筆:從當前畫筆位置移動到終點(x,y)
示例如下:
path.moveTo(100,100);
path.lineTo(300,300);
canvas.drawPath(path,paint);
3、arcTo
3.1、arcTo(RectF oval, float startAngle, float sweepAngle)
繪制圓弧:從當前畫筆位置出發,連線到內切
矩形區域oval
的圓弧的起始角度startAngle
位置(X軸正方向為0°),順時針旋轉繪制圓弧,旋轉度數為sweepAngle
(sweepAngle為負時則逆時針旋轉)
示例如下:
RectF rectF = new RectF(100,100,300,400);
path.arcTo(rectF,0,180);
canvas.drawPath(path,pathPaint);
3.2、arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)
繪制圓弧:若
forceMoveTo
為false
,則用法和arcTo(RectF oval, float startAngle, float sweepAngle)
一樣,繪制圓弧之前不會移動(moveTo)path畫筆位置
。若為true
,先強制調用moveTo移動path畫筆至圓弧起點
,再繪制圓弧。PS:如果調用arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)方法之前沒有對path進行任何操作,則forceMoveTo設置true或false效果都和設置true一樣
示例如下,注意對比之間的差異:
RectF rectF = new RectF(100,100,300,400);
path.moveTo(100,100);
path.arcTo(rectF,0,180,false);
path.close();
canvas.drawPath(path,pathPaint);
RectF rectF = new RectF(100,100,300,400);
path.moveTo(100,100);
path.arcTo(rectF,0,180,true);
path.close();
canvas.drawPath(path,pathPaint);
RectF rectF = new RectF(100,100,300,400);
path.arcTo(rectF,0,180,false);
path.close();
canvas.drawPath(path,pathPaint);
3.3、arcTo(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean forceMoveTo)
繪制圓弧:與arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)用法一樣
4、quadTo(float x1, float y1, float x2, float y2)
繪制二階貝塞爾曲線:從path畫筆當前位置出發,以(x?,y?)為控制點,向終點(x?,y?)繪制一條二階貝塞爾曲線
示例如下:
path.moveTo(100,100);
path.quadTo(200,0,400,100);
canvas.drawPath(path,pathPaint);
5、cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
繪制三階貝塞爾曲線:從path畫筆當前位置出發,以(x1,y1)為控制點1,以(x2,y2)為控制點2,向終點(x3,y3)繪制一條三階貝塞爾曲線
示例如下:
path.moveTo(100,100);
path.cubicTo(200,0,300,90,500,100);
canvas.drawPath(path,pathPaint);
圓形
其實也是由四段三階貝塞爾曲線
組成,我們繪制其中兩段看看效果即可,示例如下:
path.moveTo(300,200);
path.cubicTo(300,200+100*0.551915024494f,200+100*0.551915024494f,300,200,300);path.moveTo(200-20,300);
path.cubicTo(200-100*0.551915024494f-20,300,100-20,200+100*0.551915024494f,100-20,200);
canvas.drawPath(path,pathPaint);
二、rXxxTo方法
rXxxTo
方法的r意思是relative,即相對
的意思,方法有四個,如上圖所示,其功能與對應的xxxTo方法一樣,區別在于rXxxTo方法在繪制Path時是以當前path畫筆位置為坐標原點,即相對于path畫筆位置進行繪制,而xxxTo方法的坐標原點則與當前canvas坐標原點一致。
例如,我們使用xxxTo方法:
path.moveTo(100,100);
path.lineTo(300,300);
canvas.drawPath(path, pathPaint);
上述代碼是從(100,100)到(300,300)繪制一條直線,那么如果用rXxxTo方法,相對(100,100)這個點繪制直線,則終點應為(300-100,300-100),即終點設為(200,200),如下所示:
path.moveTo(100,100);
path.rLineTo(200,200);
canvas.drawPath(path, pathPaint);
效果都是一樣的:
三、addXxx方法
Path
類中還提供了一套addXxx
方法,字面理解就是添加一段相應的線,線可以是曲線
、完整的圓形
、矩形
等,甚至可以是另一組Path的線
。所謂添加的意思,我個人理解就是在繪制這段線前,移動(moveTo)path畫筆位置到線的起始位置,然后再繪制線
,也就是說添加的這段線,與之前繪制的Path是分離的(除非后繪制的這段線的起始點與之前Path的終點一致)
。
方法匯總如下表所示:
方法名 | 參數解析 |
---|---|
addArc(RectF oval, float startAngle, float sweepAngle) | 添加圓弧,oval:圓弧矩形區域,startAngle:起始角度,sweepAngle:圓弧旋轉的角度 |
addArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle) | 添加圓弧,left、top、right、bottom組成圓弧矩形區域,startAngle:起始角度,sweepAngle:圓弧旋轉的角度。ps:此方法在API 19以上有效 |
addCircle(float x, float y, float radius, Direction dir) | 添加圓形,x:圓形圓心的x坐標,y:圓形圓心的y坐標,radius:圓形半徑,dir:線的閉合方向(CW順時針方向 |
addOval(RectF oval, Direction dir) | 添加橢圓,oval:橢圓內切的矩形區域,dir:線的閉合方向(CW順時針方向 |
addOval(float left, float top, float right, float bottom, Direction dir) | 添加橢圓,left、top、right、bottom組成橢圓內切的矩形區域,dir:線的閉合方向(CW順時針方向 |
addRect(RectF rect, Direction dir) | 添加矩形,rect:矩形區域,dir:線的閉合方向(CW順時針方向 |
addRect(float left, float top, float right, float bottom, Direction dir) | 添加矩形,left、top、right、bottom組成矩形區域,dir:線的閉合方向(CW順時針方向 |
addRoundRect(RectF rect, float rx, float ry, Direction dir) | 添加統一圓角的圓角矩形,rect:矩形區域,rx:橢圓圓角的橫軸半徑,ry:橢圓圓角的縱軸半徑,dir:線的閉合方向(CW順時針方向 |
addRoundRect(float left, float top, float right, float bottom, float rx, float ry,Direction dir) | 添加統一圓角的圓角矩形,left、top、right、bottom組成矩形區域,rx:橢圓圓角的橫軸半徑,ry:橢圓圓角的縱軸半徑,dir:線的閉合方向(CW順時針方向 |
addRoundRect(RectF rect, float[] radii, Direction dir) | 添加非統一圓角的圓角矩形,rect:矩形區域,radii:矩形四個橢圓圓角的橫軸半徑和縱軸半徑的數組,一共8個數值,dir:線的閉合方向(CW順時針方向 |
addRoundRect(float left, float top, float right, float bottom, float[] radii,Direction dir) | 添加非統一圓角的圓角矩形,left、top、right、bottom組成矩形區域,radii:矩形四個橢圓圓角的橫軸半徑和縱軸半徑的數組,一共8個數值,dir:線的閉合方向(CW順時針方向 |
addPath(Path src) | 添加一組Path,src:要添加的Path |
addPath(Path src, float dx, float dy) | 添加一組平移后的Path,src:要添加的Path,dx:平移的x坐標,dy:平移的y坐標 |
addPath(Path src, Matrix matrix) | 添加一組經過矩陣變換后的Path,src:要添加的Path,matrix:3x3的矩陣 |
1、addArc(RectF oval, float startAngle, float sweepAngle)
添加圓弧:addArc兩個方法使用起來與arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)中forceMoveTo設置為true效果一致,就不展開贅述了
2、addCircle(float x, float y, float radius, Direction dir)
添加圓形:以點(x,y)為圓心,添加一個半徑長為radius的圓形,繪制起始角度為0°(x軸方向),繪制方向通過dir的值而定,dir為CW時順時針繪制,dir為CCW時逆時針繪制。
方法比較簡單,主要是對比CW和CCW的區別,我們用canvas.drawTextOnPath方法突顯順時針和逆時針繪制的效果,示例如下:
path.addCircle(200,150,100, Path.Direction.CW);//順時針繪制
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
path.addCircle(200,150,100, Path.Direction.CCW);//逆時針繪制
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
3、addOval(RectF oval, Direction dir)
添加橢圓:在oval矩形區域中,添加一個內切的橢圓,繪制起始角度為0°(x軸方向),繪制方向通過dir的值而定,dir為CW時順時針繪制,dir為CCW時逆時針繪制。
注:
addOval(RectF oval, Direction dir)和addOval(float left, float top, float right, float bottom, Direction dir)效果是一樣的,就不分開講了。
示例如下:
RectF rectF = new RectF(100,100,400,250);
path.addOval(rectF, Path.Direction.CW);
canvas.drawPath(path,pathPaint);
4、addRect(RectF rect, Direction dir)
添加矩形:添加一個區域為rect的矩形,繪制起點為左上角,繪制方向通過dir的值而定,dir為CW時順時針繪制,dir為CCW時逆時針繪制。
注:
addRect(RectF rect, Direction dir)和addRect(float left, float top, float right, float bottom, Direction dir)效果是一樣的,就不分開講了
示例如下:
RectF rectF = new RectF(100,100,400,250);
path.addRect(rectF, Path.Direction.CW);
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
5、addRoundRect
5.1、addRoundRect(RectF rect, float rx, float ry, Direction dir)
添加統一圓角的圓角矩形:添加一個區域為rect的圓角矩形,四個角的圓角大小一致,圓角的橫軸半徑為rx,縱軸半徑為ry,dir為CW時順時針繪制,繪制起點為左下角,dir為CCW時逆時針繪制,繪制起點為左上角(注意對比順時針和逆時針的繪制起點)。
注:
addRoundRect(RectF rect, float rx, float ry, Direction dir)和addRoundRect(float left, float top, float right, float bottom, float rx, float ry,Direction dir)效果是一樣的,就不分開講了。
示例如下:
RectF rectF = new RectF(100,100,400,350);
path.addRoundRect(rectF,60,30,Path.Direction.CW);//順時針
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
RectF rectF = new RectF(100,100,400,350);
path.addRoundRect(rectF,60,30,Path.Direction.CCW);//逆時針
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
5.2、addRoundRect(RectF rect, float[] radii, Direction dir)
添加非統一圓角的圓角矩形:添加一個區域為rect的圓角矩形,四個角的圓角的橫軸和縱軸半徑由radii數組中的8個數值決定,dir為CW時順時針繪制,繪制起點為左下角,dir為CCW時逆時針繪制,繪制起點為左上角(注意對比順時針和逆時針的繪制起點)。
注:
需要注意的是,如果radii數組中的元素小于8,系統會拋出錯誤信息radii[] needs 8 values,如下圖所示:
注:
addRoundRect(RectF rect, float[] radii, Direction dir)和addRoundRect(float left, float top, float right, float bottom, float[] radii,Direction dir)效果是一樣的,就不分開講了。
RectF rectF = new RectF(100,100,400,350);
float[] radii = {60,30,30,70,100,100,10,40};
path.addRoundRect(rectF,radii,Path.Direction.CW);
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
6、addPath(Path src)
添加一組名為src的Path副本
Path copyPath = new Path();
copyPath.moveTo(100,100);
copyPath.lineTo(150,200);
copyPath.quadTo(200,100,350,200);
copyPath.lineTo(100,250);
copyPath.close();
path.addPath(copyPath);
canvas.drawPath(path,pathPaint);
6.1、addPath(Path src, float dx, float dy)
添加一組名為src的Path副本,然后將其進行平移,x軸上的平移距離為dx,y軸上的平移距離為dy
Path copyPath = new Path();
copyPath.moveTo(100,100);
copyPath.lineTo(150,200);
copyPath.quadTo(200,100,350,200);
copyPath.lineTo(100,250);
copyPath.close();
path.addPath(copyPath,300,0);//向x軸正方向平移300像素距離
canvas.drawPath(path,pathPaint);
6.2、addPath(Path src, Matrix matrix)
添加一組名為src的Path副本,然后將其進行矩陣變換,矩陣為matrix(3x3的矩陣)
Path copyPath = new Path();
copyPath.moveTo(100,100);
copyPath.lineTo(150,200);
copyPath.quadTo(200,100,350,200);
copyPath.lineTo(100,250);
copyPath.close();Matrix mMatrix = new Matrix();
mMatrix.setScale(1,-1);//以x軸為中線進行翻轉
mMatrix.postRotate(90);//以坐標軸原點為中心點順時針旋轉90°path.addPath(copyPath,mMatrix);
canvas.drawPath(path,pathPaint);
四、填充模式
方法名 | 參數解析 |
---|---|
setFillType(FillType ft) | 設置Path的填充模式,ft:填充類型,有EVEN_ODD ,INVERSE_EVEN_ODD ,WINDING ,INVERSE_WINDING 四種模式 |
getFillType() | 獲取當前Path的填充模式 |
isInverseFillType() | 判斷當前Path填充模式是否是反向規則(INVERSE_XXX) |
toggleInverseFillType() | 當前Path的填充模式與其反向規則模式進行相互切換 |
五、其他方法
方法名 | 參數解析 |
---|---|
close() | 封閉當前Path,連接起點和終點 |
reset() | 清空Path中的所有直線和曲線,保留填充模式設置,不保留Path上相關的數據結構 |
rewind() | 清空Path中的所有直線和曲線,不保留填充模式設置,但會保留Path上相關的數據結構,以便高效地復用 |
set(Path src) | 用名為src的Path替換當前的Path |
op(Path path, Op op) | 當前Path與名為path的Path進行布爾運算(取差集、交集、并集等),op:運算邏輯,有DIFFERENCE(差集),REVERSE_DIFFERENCE(差集),INTERSECT(交集),UNION(并集),XOR(異或)五種運算邏輯可選。ps:此方法在API 19以上有效 |
offset(float dx, float dy) | 平移當前Path,x軸上平移的距離為dx,y軸上平移的距離為dy |
offset(float dx, float dy, Path dst) | 平移名為dst的Path,x軸上平移的距離為dx,y軸上平移的距離為dy |
transform(Matrix matrix) | 對當前Path進行矩陣變換,矩陣為matrix(3x3矩陣) |
transform(Matrix matrix, Path dst) | 對名為dst的Path進行矩陣變換,矩陣為matrix(3x3矩陣) |
setLastPoint(float dx, float dy) | 設置終點,設置當前Path最后一個點的位置為(dx,dy) |
isEmpty() | 判斷當前Path是否為空 |
isConvex() | 判斷當前Path圍成的圖形是否凸多邊形。ps:此方法在API 21以上有效 |
isRect(RectF rect) | 判斷當前Path是否為矩形,如是,則將當前Path存儲到新建的rect中 |
注:
這里大多數方法都比較簡單,有些之前已經應用過,就不展開來講了,下面介紹一下其中比較特別且常用的幾個方法。
1、op(Path path, Op op) 布爾運算
前面的表格我們提到參數op共有五種運算邏輯可選,下面我們就來看看這五種運算邏輯是如何影響兩個Path之間的關系的,我們先用不同的顏色繪制出一個矩形和一個圓形,觀察一下它們的位置和關系:
Path path1 = new Path();
path1.addRect(100,100,300,300, Path.Direction.CW);
pathPaint.setColor(Color.GREEN);
canvas.drawPath(path1,pathPaint);Path path2 = new Path();
path2.addCircle(300,250,100,Path.Direction.CW);
pathPaint.setColor(Color.RED);
canvas.drawPath(path2,pathPaint);
下面我們對這兩個Path進行布爾運算:
1.1、DIFFERENCE(差集)
若op方法的調用關系為path1.op(path2, Path.Op.DIFFERENCE),則運算結果是path1減去與path2的交集后剩下的部分,即path1與path2的并集減去path2部分
Path path1 = new Path();
path1.addRect(100,100,300,300, Path.Direction.CW);Path path2 = new Path();
path2.addCircle(300,250,100,Path.Direction.CW);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path1.op(path2, Path.Op.DIFFERENCE);//path1與path2進行布爾運算,結果保存至path1canvas.drawPath(path1,pathPaint);
}//也可以這樣寫
Path path3 = new Path();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path3.op(path1,path2,Path.Op.DIFFERENCE);//path1與path2進行布爾運算,結果保存至path3canvas.drawPath(path3,pathPaint);
}
可以用path1.op直接運算,也可以新建一個path3保存path1和path2的運算結果,效果都是一樣的
1.2、REVERSE_DIFFERENCE(差集)
若op方法的調用關系為path1.op(path2, Path.Op.REVERSE_DIFFERENCE),則運算結果是path2減去與path1的交集后剩下的部分,即path1與path2的并集減去path1部分
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path1.op(path2, Path.Op.REVERSE_DIFFERENCE);//path1與path2進行布爾運算,結果保存至path1canvas.drawPath(path1,pathPaint);
}//也可以這樣寫
Path path3 = new Path();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path3.op(path1,path2,Path.Op.REVERSE_DIFFERENCE);//path1與path2進行布爾運算,結果保存至path3canvas.drawPath(path3,pathPaint);
}
1.3、INTERSECT(交集)
若op方法的調用關系為path1.op(path2, Path.Op.INTERSECT),則運算結果是path1與path2的交集
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path1.op(path2, Path.Op.INTERSECT);//path1與path2進行布爾運算,結果保存至path1canvas.drawPath(path1,pathPaint);
}//也可以這樣寫
Path path3 = new Path();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path3.op(path1,path2,Path.Op.INTERSECT);//path1與path2進行布爾運算,結果保存至path3canvas.drawPath(path3,pathPaint);
}
1.4、UNION(并集)
若op方法的調用關系為path1.op(path2, Path.Op.UNION),則運算結果是path1與path2的并集
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path1.op(path2, Path.Op.UNION);//path1與path2進行布爾運算,結果保存至path1canvas.drawPath(path1,pathPaint);
}//也可以這樣寫
Path path3 = new Path();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path3.op(path1,path2,Path.Op.UNION);//path1與path2進行布爾運算,結果保存至path3canvas.drawPath(path3,pathPaint);
}
1.5、XOR(異或)
若op方法的調用關系為path1.op(path2, Path.Op.XOR),則運算結果是path1與path2的并集減去path1與path2的交集
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path1.op(path2, Path.Op.XOR);//path1與path2進行布爾運算,結果保存至path1canvas.drawPath(path1,pathPaint);
}//也可以這樣寫
Path path3 = new Path();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {path3.op(path1,path2,Path.Op.XOR);//path1與path2進行布爾運算,結果保存至path3canvas.drawPath(path3,pathPaint);
}
2、setLastPoint(float dx, float dy)
當Path在調用setLastPoint方法之前執行了某項操作時(繪制直線或曲線等),會將該操作的終點強制設置為(dx,dy)并連線(線的曲直取決于該操作本身是繪制直線還是曲線)
理解這個方法之前,首先我們要知道無論是使用addXxx方法還是xxxTo方法等在繪制過程中其實都是根據一堆點的集合,按順序連線(直線或曲線)后繪制出Path最終的樣子,setLastPoint方法正是改變此方法調用之前點的集合中最后一個點的位置。下面我們通過封閉圖形(矩形)和非封閉圖形(一段圓弧)的例子更好地理解這個方法。
//用綠線繪制一個矩形
path.addRect(new RectF(100,100,300,300), Path.Direction.CW);
pathPaint.setColor(Color.GREEN);
canvas.drawPath(path,pathPaint);//強制設置最后一個點為(150,250),用紅線繪制觀察變化
path.reset();
path.addRect(new RectF(100,100,300,300), Path.Direction.CW);
path.setLastPoint(150,250);
pathPaint.setColor(Color.RED);
canvas.drawPath(path,pathPaint);
//用綠線繪制一個旋轉180°的圓弧
path.addArc(new RectF(100,100,300,300),0,180);
pathPaint.setColor(Color.GREEN);
canvas.drawPath(path,pathPaint);//強制設置最后一個點為(200,200),用紅線繪制觀察變化
path.reset();
path.addArc(new RectF(100,100,300,300),0,180);
path.setLastPoint(200,200);
pathPaint.setColor(Color.RED);
canvas.drawPath(path,pathPaint);