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_ODDWINDINGINVERSE_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軸上平移的距離為dx,y軸上平移的距離為dy
offset(float dx, float dy, Path dst) 平移名為dst的Pathx軸上平移的距離為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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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

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