版權(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)
繪制圓弧荐类,若forceMoveTo為false怖现,則用法和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è)置true或false效果都和設(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) | 添加一組Path,src:要添加的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的值而定能耻,dir為CW時(shí)順時(shí)針繪制赏枚,dir為CCW時(shí)逆時(shí)針繪制
方法比較簡(jiǎn)單,主要是對(duì)比CW和CCW的區(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的值而定,dir為CW時(shí)順時(shí)針繪制帕涌,dir為CCW時(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的值而定亲澡,dir為CW時(shí)順時(shí)針繪制钦扭,dir為CCW時(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癞己,dir為CW時(shí)順時(shí)針繪制膀斋,繪制起點(diǎn)為左下角,dir為CCW時(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ù)值決定绩社,dir為CW時(shí)順時(shí)針繪制摔蓝,繪制起點(diǎn)為左下角,dir為CCW時(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)
添加一組名為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);
addPath(Path src, float dx, float dy)
添加一組名為src的Path副本,然后將其進(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)
添加一組名為src的Path副本,然后將其進(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_ODD ,INVERSE_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軸上平移的距離為dx,y軸上平移的距離為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)可展開收起的水平菜單欄