您好,登錄后才能下訂單哦!
這篇文章主要講解了“View繪圖之Path怎么使用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“View繪圖之Path怎么使用”吧!
path類是一個(gè)非常有用的類,他可以預(yù)先在view上講N個(gè)點(diǎn)連成一條“路徑”,然后調(diào)用Canvas的drawPath(path,paint)即可沿著路徑繪制圖形,并且Android還為路徑提供了pathEffect來繪制效果,pathEffect包含了如下子類
-ComposePathEffect
-ComnerPathEffect
-DashPathEffect
-DiscretePathEffect
-PathDashPathEffect
-SunPathEffect
代碼如下
運(yùn)行效果
package tester.ermu.com.canvasdemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ComposePathEffect; import android.graphics.CornerPathEffect; import android.graphics.DashPathEffect; import android.graphics.DiscretePathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathDashPathEffect; import android.graphics.PathEffect; import android.graphics.SumPathEffect; import android.util.AttributeSet; import android.view.View; /** * Created by ENZ on 2016/11/17. */ public class PathText extends View { private float phase; //線條的集合, PathEffect[] effects = new PathEffect[7]; int[] colors; private Paint paint; Path path; public PathText(Context context, AttributeSet attrs) { super(context, attrs); //----------------------第一步------------------------------- //創(chuàng)建一個(gè)畫筆對(duì)象,設(shè)置畫筆類型和畫筆的大小 paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(8); //------------------------第二步----------------------------- /* 創(chuàng)建一個(gè)Path對(duì)象 * 起始點(diǎn)為moveTo(0, 0) * */ path = new Path(); path.moveTo(0, 0); //--------------------------第三步--------------------------- /* * /生成50個(gè)點(diǎn),隨機(jī)生成它們的Y坐標(biāo),并將它們連成一條Path * */ for (int i = 1; i <= 50; i++) { path.lineTo(i * 20, (float) Math.random() *100); } // 初始化7個(gè)顏色 colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.RED, Color.GRAY }; } public PathText(Context context){ super(context); } //-------------------------第四步---------------------------- @Override protected void onDraw(Canvas canvas){ // 將背景填充成白色 canvas.drawColor(Color.WHITE); // --------------------------------------------------- //第一條線,什么效果都不加 /* * 效果:無 * */ effects[0] = null; // --------------------------------------------------- /*第二條線 * 使用CornerPathEffect路徑效果 * 效果:拐角平滑,平滑度為10 * */ effects[1] = new CornerPathEffect(10); // --------------------------------------------------- /*第三條線 * 初始化DiscretePathEffect,使得在原來路徑的基礎(chǔ)上發(fā)生打散效果。 * 通過構(gòu)造DiscretePathEffect(float segmentLength,float deviation) * segmentLength指定最大的段長(zhǎng),deviation指定偏離量。 * */ effects[2] = new DiscretePathEffect(1.0f, 5.0f); // --------------------------------------------------- /*第四條線 * 初始化DashPathEffect * 這個(gè)類的作用就是將Path的線段虛線化。 * 構(gòu)造函數(shù)為DashPathEffect(float[] intervals, float offset) * 其中intervals為虛線的ON和OFF數(shù)組,該數(shù)組的length必須大于等于2,phase為繪制時(shí)的偏移量。 * */ effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 },phase); // --------------------------------------------------- /*第五條線 * 使用Path圖形來填充當(dāng)前的路徑 * 構(gòu)造函數(shù)為PathDashPathEffect (Path shape, float advance, float phase,PathDashPathEffect.Stylestyle)。 * shape則是指填充圖形,advance指每個(gè)圖形間的間距,phase為繪制時(shí)的偏移量, * * style為該類自由的枚舉值,有三種情況:Style.ROTATE、Style.MORPH和 * ROTATE的情況下,線段連接處的圖形轉(zhuǎn)換以旋轉(zhuǎn)到與下一段移動(dòng)方向相一致的角度進(jìn)行旋轉(zhuǎn), * MORPH時(shí)圖形會(huì)以發(fā)生拉伸或壓縮等變形的情況與下一段相連接, * TRANSLATE時(shí),圖形會(huì)以位置平移的方式與下一段相連接。 * */ Path p = new Path(); p.addRect(0, 0, 8, 8, Path.Direction.CCW); effects[4] = new PathDashPathEffect(p, 12, phase,PathDashPathEffect.Style.ROTATE); // --------------------------------------------------- /*第六條線 * 這個(gè)類需要兩個(gè)PathEffect參數(shù)來構(gòu)造一個(gè)實(shí)例 * ComposePathEffect (PathEffect outerpe,PathEffect innerpe)表現(xiàn)時(shí) * 會(huì)首先將innerpe表現(xiàn)出來,然后再在innerpe的基礎(chǔ)上去增加outerpe的效果。 * * 下面我就是用了effects[2], effects[4] * */ // 初始化ComposePathEffect effects[5] = new ComposePathEffect(effects[2], effects[4]); // --------------------------------------------------- /*第七條線 * 這個(gè)類也需要兩個(gè)PathEffect作為參數(shù)SumPathEffect(PathEffect first,PathEffect second), * 但與ComposePathEffect不同的是,在表現(xiàn)時(shí),會(huì)分別對(duì)兩個(gè)參數(shù)的效果各自獨(dú)立進(jìn)行表現(xiàn),然后將兩個(gè)效果簡(jiǎn)單的重疊在一起顯示出來。 * */ effects[6] = new SumPathEffect(effects[4], effects[3]); // --------------------------------------------------- // 將畫布移動(dòng)到(8、8)處開始繪制 canvas.translate(16, 100); // 依次使用7種不同路徑效果、7種不同的顏色來繪制路徑 for (int i = 0; i < effects.length; i++){ paint.setPathEffect(effects[i]); paint.setColor(colors[i]); canvas.drawPath(path, paint); canvas.translate(0, 160); } // 改變phase值,形成動(dòng)畫效果 // --------------------------------------------------- /* * 使用重新繪制方法invalidate();,偏移量加一,形成運(yùn)行效果 * */ phase += 1; invalidate(); } }
這里就不在介紹沒個(gè)子類的屬性了,代碼很簡(jiǎn)單,步驟如下:
1、創(chuàng)建一個(gè)類繼承view
2、定義一個(gè)線集合,用來添加我們繪制的7跳線,通過一個(gè)for循環(huán)依次繪制
3、上面代碼中,在注釋中前四步是準(zhǔn)備工作,創(chuàng)建畫筆、設(shè)置畫布顏色、設(shè)定轉(zhuǎn)折點(diǎn)的數(shù)量及每條線的顏色
4、引用子類對(duì)象 ,來為每條線添加不同的屬性。
5、進(jìn)行繪制,并且設(shè)置偏移量加1,并且設(shè)置重繪方法,實(shí)現(xiàn)一個(gè)動(dòng)畫效果
代碼結(jié)構(gòu)視圖
1.1 lineTo(float x, float y)
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 連接路徑到點(diǎn)[100,100] mPath.lineTo(100, 100); // 繪制路徑 canvas.drawPath(mPath, mPaint); }
多次調(diào)用lineTo方法來繪制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.lineTo(300, 100); mPath.lineTo(400, 200); mPath.lineTo(200, 200); // 繪制路徑 canvas.drawPath(mPath, mPaint); }
1.2 moveTo(float x, float y) +close()方法閉合曲線
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.lineTo(300, 100); mPath.lineTo(400, 200); mPath.lineTo(200, 200); // 閉合曲線 mPath.close(); // 繪制路徑 canvas.drawPath(mPath, mPaint); }
二、畫貝賽爾曲線
quadTo(float x1, float y1, float x2, float y2)
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)起點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.quadTo(200, 200, 300, 100); canvas.drawPath(mPath, mPaint); }
2.3 cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)起點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.cubicTo(200, 200, 300, 0, 400, 100); canvas.drawPath(mPath, mPaint); }
arcTo (RectF oval, float startAngle, float sweepAngle) 是一個(gè)畫弧線的方法,其實(shí)說白了就是從圓或橢圓上截取一部分而已。
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)起點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) RectF oval = new RectF(100, 100, 200, 200); mPath.arcTo(oval, 0, 90); canvas.drawPath(mPath, mPaint); }
arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) 它會(huì)強(qiáng)制起點(diǎn)為繪制的起始點(diǎn),而不是畫布的左上角。
我們來看看效果:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)起點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) RectF oval = new RectF(100, 100, 200, 200); mPath.arcTo(oval, 0, 90,true); canvas.drawPath(mPath, mPaint); }
rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) rLineTo(float dx, float dy) rMoveTo(float dx, float dy) rQuadTo(float dx1, float dy1, float dx2, float dy2)
例如: 起點(diǎn)(100,100)到終點(diǎn)(200,200)
XXXTo繪制的距離就是,這里的move和lineTo的坐標(biāo)都是對(duì)于畫布左上角(0,0)來說。100到200的距離,繪制的總長(zhǎng)度為00到200,也就是200距離
而rXXXTo繪制的距離就是相對(duì)于100起點(diǎn),再繪制200的距離。繪制的總長(zhǎng)度就是300
我們寫一個(gè)例子
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.lineTo(200, 200); canvas.drawPath(mPath, mPaint); }
這里的move和lineTo的坐標(biāo)都是對(duì)于畫布左上角(0,0)來說的,是一個(gè)絕對(duì)坐標(biāo)。而我們換為mPath.rLineTo(200, 200); 后呢?
是不是感覺線段長(zhǎng)了很多,因?yàn)檫@里的(200,200)是相對(duì)于開始點(diǎn)(100,100)來說的,是相對(duì)坐標(biāo)。如果換算成絕對(duì)坐標(biāo)就是繪制一條(100,100)到(300,300)之間的線段。
其實(shí),這個(gè)前綴“r”也就是relative(相對(duì))的簡(jiǎn)寫!
XXXTo方法可以連接Path中的曲線,而Path提供的另一系列addXXX方法則可以讓我們直接往Path中添加一些曲線,比如
addArc(RectF oval, float startAngle, float sweepAngle) : 它允許我們將一段弧形添加至Path,注意這里我用到了“添加”這個(gè)詞匯,
也就是說,通過addXXX方法添加到Path中的曲線是不會(huì)和上一次的曲線進(jìn)行連接的:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(5); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)點(diǎn)至[100,100] mPath.moveTo(100, 100); // 連接路徑到點(diǎn) mPath.lineTo(200, 200); // 添加一條弧線到Path中 RectF oval = new RectF(100, 100, 300, 400); mPath.addArc(oval, 0, 90); canvas.drawPath(mPath, mPaint); }
如圖和代碼所示,雖然我們先繪制了由[100,100]到[200,200]的線段,但是在我們往Path中添加了一條弧線后該弧線并沒與線段連接。
除了addArc,Path還提供了一系列的add方法:
addCircle(float x, float y, float radius, Path.Direction dir)
addOval(float left, float top, float right, float bottom, Path.Direction dir)
addRect(float left, float top, float right, float bottom, Path.Direction dir)
addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir)
這些方法和addArc有很明顯的區(qū)別,就是多了一個(gè)Path.Direction參數(shù),其他呢都大同小異,除此之外不知道大家還發(fā)現(xiàn)沒有,addArc是往Path中添加一段弧,說白了就是一條開放的曲線,而上述幾種方法都是一個(gè)具體的圖形,或者說是一條閉合的曲線,Path.Direction的意思就是標(biāo)識(shí)這些閉合曲線的閉合方向。Path.Direction只有兩個(gè)常量值CCW和CW分別表示逆時(shí)針方向閉合和順時(shí)針方向閉合。
例如順時(shí)針方向閉合
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); // 實(shí)例化路徑 mPath = new Path(); // 移動(dòng)起點(diǎn)至[100,100] mPath.moveTo(100, 100); // 添加一條弧線到Path中 RectF oval = new RectF(100, 100, 300, 400); mPath.addOval(oval, Path.Direction.CW); canvas.drawPath(mPath, mPaint); mPaint.setTextSize(50); // 繪制路徑上的文字 canvas.drawTextOnPath("123456789", mPath, 0, 0, mPaint); }
如果我們換作:mPath.addOval(oval, Path.Direction.CCW);
逆時(shí)針封閉
感謝各位的閱讀,以上就是“View繪圖之Path怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)View繪圖之Path怎么使用這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。