Android知識(shí)總結(jié)——Path常用方法解析

版權(quán)聲明:本文為博主原創(chuàng)文章镰烧,未經(jīng)博主允許不得轉(zhuǎn)載沥寥。
系列教程:Android開發(fā)之從零開始系列

大家要是看到有錯(cuò)誤的地方或者有啥好的建議,歡迎留言評(píng)論

前言:開發(fā)過程中很容易忘記一些API的使用方法埂奈,網(wǎng)上搜索或者在源碼里找也很難短時(shí)間內(nèi)篩選出自己需要的嗜湃,遂自己將這些知識(shí)總結(jié)一番


常用API解析與示例

一奈应、xxxTo方法

Path類中提供了一套xxxTo方法,其作用是從起點(diǎn)到終點(diǎn)移動(dòng)path畫筆并繪制線(moveTo方法只移動(dòng)path畫筆不繪制線)购披,線有直線和曲線杖挣。方法匯總?cè)缦卤硭?/p>

方法名 參數(shù)解析
lineTo(float x, float y) 繪制直線x:終點(diǎn)x坐標(biāo)值今瀑,y:終點(diǎn)y坐標(biāo)值
moveTo(float x, float y) 移動(dòng)畫筆程梦,x:終點(diǎn)x坐標(biāo)值点把,y:終點(diǎn)y坐標(biāo)值
arcTo(RectF oval, float startAngle, float sweepAngle) 繪制圓弧橘荠,oval:圓弧矩形區(qū)域,startAngle:起始角度郎逃,sweepAngle:圓弧旋轉(zhuǎn)的角度
arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo) 繪制圓弧哥童,oval:圓弧矩形區(qū)域,startAngle:起始角度褒翰,sweepAngle:圓弧旋轉(zhuǎn)的角度贮懈,forceMoveTo:是否在繪制圓弧前移動(dòng)(moveTo)path畫筆位置
arcTo(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean forceMoveTo) 繪制圓弧left优训、top朵你、right、bottom組成圓弧矩形區(qū)域揣非,startAngle:起始角度抡医,sweepAngle:圓弧旋轉(zhuǎn)的角度,forceMoveTo:是否在繪制圓弧前移動(dòng)(moveTo)path畫筆位置
quadTo(float x1, float y1, float x2, float y2) 繪制二階貝塞爾曲線早敬,控制點(diǎn)坐標(biāo):(x1,y1)忌傻,終點(diǎn)坐標(biāo):(x2,y2)
cubicTo(float x1, float y1, float x2, float y2,float x3, float y3) 繪制三階貝塞爾曲線,其中控制點(diǎn)1坐標(biāo)為(x1,y1)搞监,控制點(diǎn)2坐標(biāo)為(x2,y2)水孩,終點(diǎn)坐標(biāo)為(x3,y3)

1.lineTo(float x, float y)

繪制直線,從當(dāng)前畫筆位置出發(fā)琐驴,連接終點(diǎn)(x,y)俘种,示例如下

示例如下

path.lineTo(300,300);
canvas.drawPath(path,paint);

2.moveTo(float x, float y)

移動(dòng)畫筆秤标,從當(dāng)前畫筆位置移動(dòng)到終點(diǎn)(x,y)

示例如下

path.moveTo(100,100);
path.lineTo(300,300);
canvas.drawPath(path,paint);

3.arcTo(RectF oval, float startAngle, float sweepAngle)

繪制圓弧,從當(dāng)前畫筆位置出發(fā)安疗,連線到內(nèi)切矩形區(qū)域oval的圓弧的起始角度startAngle位置(X軸正方向?yàn)?°)抛杨,順時(shí)針旋轉(zhuǎn)繪制圓弧,旋轉(zhuǎn)度數(shù)為sweepAngle(sweepAngle為負(fù)時(shí)則逆時(shí)針旋轉(zhuǎn))

示例如下

RectF rectF = new RectF(100,100,300,400);
path.arcTo(rectF,0,180);
canvas.drawPath(path,pathPaint);

arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)

繪制圓弧荐类,若forceMoveTofalse怖现,則用法和arcTo(RectF oval, float startAngle, float sweepAngle)一樣,繪制圓弧之前不會(huì)移動(dòng)(moveTo)path畫筆位置玉罐。若為true屈嗤,先強(qiáng)制調(diào)用moveTo移動(dòng)path畫筆至圓弧起點(diǎn),再繪制圓弧吊输。ps:如果調(diào)用arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)方法之前沒有對(duì)path進(jìn)行任何操作饶号,則forceMoveTo設(shè)置truefalse效果都和設(shè)置true一樣

示例如下,注意對(duì)比之間的差異

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);

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畫筆當(dāng)前位置出發(fā)季蚂,以(x?,y?)為控制點(diǎn)茫船,向終點(diǎn)(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畫筆當(dāng)前位置出發(fā),以(x1,y1)為控制點(diǎn)1扭屁,以(x2,y2)為控制點(diǎn)2算谈,向終點(diǎn)(x3,y3)繪制一條三階貝塞爾曲線

簡(jiǎn)單示例如下

path.moveTo(100,100);
path.cubicTo(200,0,300,90,500,100);
canvas.drawPath(path,pathPaint);

圓形其實(shí)也是由四段三階貝塞爾曲線組成,我們繪制其中兩段看看效果即可料滥,示例如下

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,即相對(duì)的意思葵腹,方法有四個(gè)高每,如上圖所示,其功能與對(duì)應(yīng)的xxxTo方法一樣践宴,區(qū)別在于rXxxTo方法在繪制Path時(shí)是以當(dāng)前path畫筆位置為坐標(biāo)原點(diǎn)鲸匿,即相對(duì)于path畫筆位置進(jìn)行繪制,而xxxTo方法的坐標(biāo)原點(diǎn)則與當(dāng)前canvas坐標(biāo)原點(diǎn)一致阻肩。例如带欢,我們使用xxxTo方法

path.moveTo(100,100);
path.lineTo(300,300);
canvas.drawPath(path, pathPaint);

上述代碼是從(100,100)到(300,300)繪制一條直線,那么如果用rXxxTo方法磺浙,相對(duì)(100,100)這個(gè)點(diǎn)繪制直線洪囤,則終點(diǎn)應(yīng)為(300-100,300-100),即終點(diǎn)設(shè)為(200,200)撕氧,如下所示

path.moveTo(100,100);
path.rLineTo(200,200);
canvas.drawPath(path, pathPaint);

效果都是一樣的


三瘤缩、addXxx方法

Path類中還提供了一套addXxx方法,字面理解就是添加一段相應(yīng)的線伦泥,線可以是曲線剥啤、完整的圓形锦溪、矩形等,甚至可以是另一組Path的線府怯。所謂添加的意思刻诊,我個(gè)人理解就是在繪制這段線前移動(dòng)(moveTo)path畫筆位置到線的起始位置牺丙,然后再繪制線则涯,也就是說添加的這段線,與之前繪制的Path是分離的(除非后繪制的這段線的起始點(diǎn)與之前Path的終點(diǎn)一致)冲簿。方法匯總?cè)缦卤硭?/p>

方法名 參數(shù)解析
addArc(RectF oval, float startAngle, float sweepAngle) 添加圓弧粟判,oval:圓弧矩形區(qū)域驻襟,startAngle:起始角度稠通,sweepAngle:圓弧旋轉(zhuǎn)的角度
addArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle) 添加圓弧溃斋,left陶舞、top、right烹棉、bottom組成圓弧矩形區(qū)域滥崩,startAngle:起始角度涂臣,sweepAngle:圓弧旋轉(zhuǎn)的角度惨险。ps:此方法在API 19以上有效
addCircle(float x, float y, float radius, Direction dir) 添加圓形羹幸,x:圓形圓心的x坐標(biāo),y:圓形圓心的y坐標(biāo)平道,radius:圓形半徑睹欲,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addOval(RectF oval, Direction dir) 添加橢圓供炼,oval:橢圓內(nèi)切的矩形區(qū)域一屋,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addOval(float left, float top, float right, float bottom, Direction dir) 添加橢圓left袋哼、top冀墨、right、bottom組成橢圓內(nèi)切的矩形區(qū)域涛贯,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRect(RectF rect, Direction dir) 添加矩形诽嘉,rect:矩形區(qū)域,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRect(float left, float top, float right, float bottom, Direction dir) 添加矩形弟翘,left虫腋、top、right稀余、bottom組成矩形區(qū)域悦冀,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRoundRect(RectF rect, float rx, float ry, Direction dir) 添加統(tǒng)一圓角的圓角矩形rect:矩形區(qū)域睛琳,rx:橢圓圓角的橫軸半徑盒蟆,ry:橢圓圓角的縱軸半徑踏烙,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRoundRect(float left, float top, float right, float bottom, float rx, float ry,Direction dir) 添加統(tǒng)一圓角的圓角矩形left历等、top讨惩、right、bottom組成矩形區(qū)域寒屯,rx:橢圓圓角的橫軸半徑荐捻,ry:橢圓圓角的縱軸半徑,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRoundRect(RectF rect, float[] radii, Direction dir) 添加非統(tǒng)一圓角的圓角矩形寡夹,rect:矩形區(qū)域靴患,radii:矩形四個(gè)橢圓圓角的橫軸半徑和縱軸半徑的數(shù)組,一共8個(gè)數(shù)值要出,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addRoundRect(float left, float top, float right, float bottom, float[] radii,Direction dir) 添加非統(tǒng)一圓角的圓角矩形鸳君,left、top患蹂、right或颊、bottom組成矩形區(qū)域,radii:矩形四個(gè)橢圓圓角的橫軸半徑和縱軸半徑的數(shù)組传于,一共8個(gè)數(shù)值囱挑,dir:線的閉合方向(CW順時(shí)針方向 | CCW逆時(shí)針方向)
addPath(Path src) 添加一組Pathsrc:要添加的Path
addPath(Path src, float dx, float dy) 添加一組平移后的Path沼溜,src:要添加的Path平挑,dx:平移的x坐標(biāo),dy:平移的y坐標(biāo)
addPath(Path src, Matrix matrix) 添加一組經(jīng)過矩陣變換后的Path系草,src:要添加的Path通熄,matrix:3x3的矩陣

1.addArc(RectF oval, float startAngle, float sweepAngle)

addArc兩個(gè)方法使用起來與arcTo(RectF oval, float startAngle, float sweepAngle,boolean forceMoveTo)forceMoveTo設(shè)置為true效果一致,就不展開贅述了


2.addCircle(float x, float y, float radius, Direction dir)

以點(diǎn)(x,y)為圓心找都,添加一個(gè)半徑長(zhǎng)為radius圓形唇辨,繪制起始角度為0°(x軸方向),繪制方向通過dir的值而定能耻,dirCW時(shí)順時(shí)針繪制赏枚,dirCCW時(shí)逆時(shí)針繪制

方法比較簡(jiǎn)單,主要是對(duì)比CWCCW的區(qū)別晓猛,我們用canvas.drawTextOnPath方法突顯順時(shí)針逆時(shí)針繪制的效果饿幅,示例如下

path.addCircle(200,150,100, Path.Direction.CW);//順時(shí)針繪制
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);
path.addCircle(200,150,100, Path.Direction.CCW);//逆時(shí)針繪制
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);

3.addOval(RectF oval, Direction dir)

oval矩形區(qū)域中,添加一個(gè)內(nèi)切的橢圓戒职,繪制起始角度為0°(x軸方向)栗恩,繪制方向通過dir的值而定,dirCW時(shí)順時(shí)針繪制帕涌,dirCCW時(shí)逆時(shí)針繪制

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)

添加一個(gè)區(qū)域?yàn)?strong>rect的矩形续徽,繪制起點(diǎn)為左上角,繪制方向通過dir的值而定亲澡,dirCW時(shí)順時(shí)針繪制钦扭,dirCCW時(shí)逆時(shí)針繪制

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(RectF rect, float rx, float ry, Direction dir)

添加一個(gè)區(qū)域?yàn)?strong>rect的圓角矩形床绪,四個(gè)角的圓角大小一致客情,圓角的橫軸半徑為rx縱軸半徑為ry癞己,dirCW時(shí)順時(shí)針繪制膀斋,繪制起點(diǎn)為左下角dirCCW時(shí)逆時(shí)針繪制痹雅,繪制起點(diǎn)為左上角(注意對(duì)比順時(shí)針和逆時(shí)針的繪制起點(diǎn)

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);//順時(shí)針
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);//逆時(shí)針
canvas.drawPath(path,pathPaint);
canvas.drawTextOnPath("繪制順序", path, 0, 0, paint);

addRoundRect(RectF rect, float[] radii, Direction dir)

添加一個(gè)區(qū)域?yàn)?strong>rect的圓角矩形,四個(gè)角的圓角的橫軸和縱軸半徑由radii數(shù)組中的8個(gè)數(shù)值決定绩社,dirCW時(shí)順時(shí)針繪制摔蓝,繪制起點(diǎn)為左下角dirCCW時(shí)逆時(shí)針繪制愉耙,繪制起點(diǎn)為左上角(注意對(duì)比順時(shí)針和逆時(shí)針的繪制起點(diǎn)

需要注意的是贮尉,如果radii數(shù)組中的元素小于8,系統(tǒng)會(huì)拋出錯(cuò)誤信息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)

添加一組名為srcPath副本

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);

addPath(Path src, float dx, float dy)

添加一組名為srcPath副本,然后將其進(jìn)行平移赌渣,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);

addPath(Path src, Matrix matrix)

添加一組名為srcPath副本,然后將其進(jìn)行矩陣變換锡垄,矩陣為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軸為中線進(jìn)行翻轉(zhuǎn)
mMatrix.postRotate(90);//以坐標(biāo)軸原點(diǎn)為中心點(diǎn)順時(shí)針旋轉(zhuǎn)90°

path.addPath(copyPath,mMatrix);
canvas.drawPath(path,pathPaint);

四沦零、填充模式

方法名 參數(shù)解析
setFillType(FillType ft) 設(shè)置Path的填充模式祭隔,ft:填充類型货岭,有EVEN_ODDINVERSE_EVEN_ODD 疾渴,WINDING 千贯,INVERSE_WINDING 四種模式
getFillType() 獲取當(dāng)前Path的填充模式
isInverseFillType() 判斷當(dāng)前Path填充模式是否是反向規(guī)則(INVERSE_XXX)
toggleInverseFillType() 當(dāng)前Path的填充模式與其反向規(guī)則模式進(jìn)行相互切換

填充模式要解釋起來還是挺費(fèi)口舌的,這里就把前輩們的博客貼出來搞坝,他們解釋得都非常清楚,我就不多贅述了
安卓自定義 View 進(jìn)階:Path 完結(jié)篇(偽)
[轉(zhuǎn)]Android Path里FillType功能


五搔谴、其他方法

方法名 參數(shù)解析
close() 封閉當(dāng)前Path,連接起點(diǎn)終點(diǎn)
reset() 清空Path中的所有直線和曲線桩撮,保留填充模式設(shè)置敦第,不保留Path上相關(guān)的數(shù)據(jù)結(jié)構(gòu)
rewind() 清空Path中的所有直線和曲線峰弹,不保留填充模式設(shè)置,但會(huì)保留Path上相關(guān)的數(shù)據(jù)結(jié)構(gòu)芜果,以便高效地復(fù)用
set(Path src) 用名為src的Path替換當(dāng)前的Path
op(Path path, Op op) 當(dāng)前Path名為path的Path進(jìn)行布爾運(yùn)算(取差集鞠呈、交集、并集等)右钾,op:運(yùn)算邏輯蚁吝,有DIFFERENCE(差集)REVERSE_DIFFERENCE(差集)舀射,INTERSECT(交集)窘茁,UNION(并集)XOR(異或)五種運(yùn)算邏輯可選脆烟。ps:此方法在API 19以上有效
offset(float dx, float dy) 平移當(dāng)前Path山林,x軸上平移的距離為dxy軸上平移的距離為dy
offset(float dx, float dy, Path dst) 平移名為dst的Path邢羔,x軸上平移的距離為dx捌朴,y軸上平移的距離為dy
transform(Matrix matrix) 對(duì)當(dāng)前Path進(jìn)行矩陣變換,矩陣為matrix(3x3矩陣)
transform(Matrix matrix, Path dst) 對(duì)名為dst的Path進(jìn)行矩陣變換张抄,矩陣為matrix(3x3矩陣)
setLastPoint(float dx, float dy) 設(shè)置終點(diǎn)砂蔽,設(shè)置當(dāng)前Path最后一個(gè)點(diǎn)的位置為(dx,dy)
isEmpty() 判斷當(dāng)前Path是否為空
isConvex() 判斷當(dāng)前Path圍成的圖形是否凸多邊形。ps:此方法在API 21以上有效
isRect(RectF rect) 判斷當(dāng)前Path是否為矩形署惯,如是左驾,則將當(dāng)前Path存儲(chǔ)到新建的rect中

這里大多數(shù)方法都比較簡(jiǎn)單,有些之前已經(jīng)應(yīng)用過极谊,就不展開來講了诡右,下面介紹一下其中比較特別且常用的幾個(gè)方法

1.op(Path path, Op op) 布爾運(yùn)算

前面的表格我們提到參數(shù)op共有五種運(yùn)算邏輯可選,下面我們就來看看這五種運(yùn)算邏輯是如何影響兩個(gè)Path之間的關(guān)系的轻猖,我們先用不同的顏色繪制出一個(gè)矩形和一個(gè)圓形帆吻,觀察一下它們的位置和關(guān)系

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);

下面我們對(duì)這兩個(gè)Path進(jìn)行布爾運(yùn)算

DIFFERENCE(差集)

若op方法的調(diào)用關(guān)系為path1.op(path2, Path.Op.DIFFERENCE),則運(yùn)算結(jié)果是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進(jìn)行布爾運(yùn)算猜煮,結(jié)果保存至path1
    canvas.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進(jìn)行布爾運(yùn)算,結(jié)果保存至path3
    canvas.drawPath(path3,pathPaint);
}

可以用path1.op直接運(yùn)算败许,也可以新建一個(gè)path3保存path1和path2的運(yùn)算結(jié)果王带,效果都是一樣的

REVERSE_DIFFERENCE(差集)

若op方法的調(diào)用關(guān)系為path1.op(path2, Path.Op.REVERSE_DIFFERENCE),則運(yùn)算結(jié)果是path2減去與path1的交集后剩下的部分市殷,即path1與path2的并集減去path1部分

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    path1.op(path2, Path.Op.REVERSE_DIFFERENCE);//path1與path2進(jìn)行布爾運(yùn)算愕撰,結(jié)果保存至path1
    canvas.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進(jìn)行布爾運(yùn)算,結(jié)果保存至path3
    canvas.drawPath(path3,pathPaint);
}
INTERSECT(交集)

若op方法的調(diào)用關(guān)系為path1.op(path2, Path.Op.INTERSECT),則運(yùn)算結(jié)果是path1與path2的交集

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    path1.op(path2, Path.Op.INTERSECT);//path1與path2進(jìn)行布爾運(yùn)算搞挣,結(jié)果保存至path1
    canvas.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進(jìn)行布爾運(yùn)算带迟,結(jié)果保存至path3
    canvas.drawPath(path3,pathPaint);
}
UNION(并集)

若op方法的調(diào)用關(guān)系為path1.op(path2, Path.Op.UNION),則運(yùn)算結(jié)果是path1與path2的并集

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    path1.op(path2, Path.Op.UNION);//path1與path2進(jìn)行布爾運(yùn)算囱桨,結(jié)果保存至path1
    canvas.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進(jìn)行布爾運(yùn)算邮旷,結(jié)果保存至path3
    canvas.drawPath(path3,pathPaint);
}
XOR(異或)

若op方法的調(diào)用關(guān)系為path1.op(path2, Path.Op.XOR),則運(yùn)算結(jié)果是path1與path2的并集減去path1與path2的交集

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    path1.op(path2, Path.Op.XOR);//path1與path2進(jìn)行布爾運(yùn)算蝇摸,結(jié)果保存至path1
    canvas.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進(jìn)行布爾運(yùn)算婶肩,結(jié)果保存至path3
    canvas.drawPath(path3,pathPaint);
}

2.setLastPoint(float dx, float dy)

當(dāng)Path在調(diào)用setLastPoint方法之前執(zhí)行了某項(xiàng)操作時(shí)(繪制直線或曲線等),會(huì)將該操作的終點(diǎn)強(qiáng)制設(shè)置為(dx,dy)連線(線的曲直取決于該操作本身是繪制直線還是曲線)

理解這個(gè)方法之前貌夕,首先我們要知道無論是使用addXxx方法還是xxxTo方法等在繪制過程中其實(shí)都是根據(jù)一堆點(diǎn)的集合律歼,按順序連線(直線或曲線)后繪制出Path最終的樣子setLastPoint方法正是改變此方法調(diào)用之前點(diǎn)的集合中最后一個(gè)點(diǎn)的位置啡专。下面我們通過封閉圖形(矩形)非封閉圖形(一段圓幌栈佟)的例子更好地理解這個(gè)方法

//用綠線繪制一個(gè)矩形
path.addRect(new RectF(100,100,300,300), Path.Direction.CW);
pathPaint.setColor(Color.GREEN);
canvas.drawPath(path,pathPaint);

//強(qiáng)制設(shè)置最后一個(gè)點(diǎn)為(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);
//用綠線繪制一個(gè)旋轉(zhuǎn)180°的圓弧
path.addArc(new RectF(100,100,300,300),0,180);
pathPaint.setColor(Color.GREEN);
canvas.drawPath(path,pathPaint);

//強(qiáng)制設(shè)置最后一個(gè)點(diǎn)為(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);

至此本篇總結(jié)到此結(jié)束畔况,若有什么遺漏和錯(cuò)誤的地方歡迎留言指出,如果大家看了感覺還不錯(cuò)麻煩點(diǎn)個(gè)贊慧库,你們的支持是我最大的動(dòng)力~

看完覺得手癢還可以去瞧瞧下面的教程博客練手哦?乛乛?
Android自定義View——從零開始實(shí)現(xiàn)圓形進(jìn)度條
Android自定義View——從零開始實(shí)現(xiàn)水波浪進(jìn)度框
Android自定義View——從零開始實(shí)現(xiàn)書籍翻頁(yè)效果(一)
Android自定義View——從零開始實(shí)現(xiàn)書籍翻頁(yè)效果(二)
Android自定義View——從零開始實(shí)現(xiàn)書籍翻頁(yè)效果(三)
Android自定義View——從零開始實(shí)現(xiàn)書籍翻頁(yè)效果(四)
Android自定義View——從零開始實(shí)現(xiàn)書籍翻頁(yè)效果(性能優(yōu)化篇)
Android自定義View——從零開始實(shí)現(xiàn)可展開收起的水平菜單欄


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跷跪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子齐板,更是在濱河造成了極大的恐慌吵瞻,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甘磨,死亡現(xiàn)場(chǎng)離奇詭異橡羞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)济舆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門卿泽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滋觉,你說我怎么就攤上這事签夭。” “怎么了椎瘟?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵覆致,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我肺蔚,道長(zhǎng),這世上最難降的妖魔是什么儡羔? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任宣羊,我火速辦了婚禮璧诵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仇冯。我一直安慰自己之宿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布苛坚。 她就那樣靜靜地躺著比被,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泼舱。 梳的紋絲不亂的頭發(fā)上等缀,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音娇昙,去河邊找鬼尺迂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冒掌,可吹牛的內(nèi)容都是我干的噪裕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼股毫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼膳音!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铃诬,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤严蓖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后氧急,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颗胡,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年吩坝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毒姨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钉寝,死狀恐怖弧呐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嵌纲,我是刑警寧澤俘枫,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站逮走,受9級(jí)特大地震影響鸠蚪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一茅信、第九天 我趴在偏房一處隱蔽的房頂上張望盾舌。 院中可真熱鬧,春花似錦蘸鲸、人聲如沸妖谴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)膝舅。三九已至,卻和暖如春窑多,著一層夾襖步出監(jiān)牢的瞬間仍稀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工怯伊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琳轿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓耿芹,卻偏偏與公主長(zhǎng)得像崭篡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吧秕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 最近項(xiàng)目中要實(shí)現(xiàn)加速球效果琉闪。是時(shí)候該學(xué)習(xí)一波了,好了廢話不多說砸彬,記筆記颠毙,還是從自己發(fā)憷的自定義view開始。 先來...
    laifrog閱讀 1,453評(píng)論 0 4
  • 參考:android繪圖之Path總結(jié)Path相關(guān)方法講解(一)path類的簡(jiǎn)化結(jié)構(gòu)圖 內(nèi)部枚舉類 構(gòu)造方法 構(gòu)造...
    蒸汽飛船閱讀 4,649評(píng)論 0 3
  • Paint 屬性配置 setAntiAlias:抗鋸齒 setDither:抗抖動(dòng) setColor,setARG...
    簡(jiǎn)祖明閱讀 909評(píng)論 0 3
  • 參考:https://juejin.im/post/58ce7fe561ff4b006c9a63c6https:/...
    zhaoyubetter閱讀 5,967評(píng)論 0 6
  • 來到簡(jiǎn)書滋迈,原因很簡(jiǎn)單霎奢,希望用筆觸記錄思考,希望用思考挖掘發(fā)現(xiàn)饼灿,希望用發(fā)現(xiàn)學(xué)會(huì)感恩幕侠,希望用感恩來引導(dǎo)美好。 ...
    銀河里的小黑豬閱讀 287評(píng)論 0 0