Android自定義view利用PathEffect實(shí)現(xiàn)動(dòng)態(tài)效果
本文實(shí)例為大家分享了Android自定義view利用PathEffect實(shí)現(xiàn)動(dòng)態(tài)效果的具體代碼,供大家參考,具體內(nèi)容如下
前言
在上一篇此類型的文章中是改變偏移量實(shí)現(xiàn)動(dòng)態(tài)效果,借助的方法是drawArc,這篇文章依然是改變偏移量,而借助的是PathEffect的子類。
效果圖:
一、首先介紹下PathEffect的一些子類
- CornerPathEffect:將Path的各個(gè)連接線段之間的夾角用一種更平滑的方式連接,類似于圓弧與切線的效果。 參數(shù)radius則是指定圓弧的半徑。
- DashPathEffect:將Path的線段虛線化,intervals為虛線的ON和OFF的數(shù)組,數(shù)組中元素?cái)?shù)目需要 >= 2; 而phase則為繪制時(shí)的偏移量。
- DiscretePathEffect:打散Path的線段,使得在原來(lái)路徑的基礎(chǔ)上發(fā)生打散效果。 segmentLength指定最大的段長(zhǎng),deviation則為繪制時(shí)的偏離量。
- PathDashPathEffect:使用Path圖形來(lái)填充當(dāng)前的路徑,shape指的填充圖形,advance是每個(gè)圖形間的間隔, phase為繪制時(shí)的偏移量。,style則是該類自由的枚舉值,有三種情況:ROTATE、MORPH和TRANSLATE。ROTATE情況下:線段連接處的圖形轉(zhuǎn)換以旋轉(zhuǎn)到與下一段移動(dòng)方向相一致的角度進(jìn)行連接。MORPH情況下:圖形會(huì)以發(fā)生拉伸或壓縮等變形的情況與下一段相連接。TRANSLATE情況下:圖形會(huì)以位置平移的方式與下一段相連接。
- ComposePathEffect:組合效果
- SumPathEffect:疊加效果,和ComposePathEffect不同,在表現(xiàn)時(shí)會(huì)將兩個(gè)參數(shù)的效果都獨(dú)立的表現(xiàn)出來(lái), 接著將兩個(gè)效果簡(jiǎn)單的重疊在一起顯示出來(lái)
二、看看子類具體的一些代碼
private static void makeEffects(PathEffect[] e, float phase) { ? ? ? ? ? ? e[0] = null; ? ? // 無(wú)效果 ? ? ? ? ? ? e[1] = new CornerPathEffect(30);//CornerPathEffect ? ? ? ? ? ? e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);//DashPathEffect ? ? ? ? ? ? e[3] = new PathDashPathEffect(makePathDash(), 12, phase, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PathDashPathEffect.Style.ROTATE);//PathDashPathEffect ? ? ? ? ? ? e[4] = new ComposePathEffect(e[2], e[1]);//ComposePathEffect ? ? ? ? ? ? e[5] = new ComposePathEffect(e[3], e[1]);//ComposePathEffect ? ? ? ? }
三、案例實(shí)現(xiàn)(CornerPathEffect,PathDashPathEffect,ComposePathEffect)
實(shí)現(xiàn)的效果是上序代碼的e[5],使用CornerPathEffect實(shí)現(xiàn)圓弧效果,而重點(diǎn)是PathDashPathEffect。
PathDashPathEffect里面有幾個(gè)參數(shù):
new PathDashPathEffect(makePathDash(), 12, phase, ? ? ? ? ?PathDashPathEffect.Style.ROTATE);
第一個(gè)參數(shù)為小path圖形,案例中博主畫的是菱形:
private static Path makePathDash() { ? ? ? ? ? ? Path p = new Path(); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? p.lineTo(4, 4); ? ? ? ? ? ? p.lineTo(8, 0); ? ? ? ? ? ? p.lineTo(4, -4); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? return p; ? ? ? ? }
第二個(gè)參數(shù)為每個(gè)圖形間的間隔。
第三個(gè)參數(shù)為繪制時(shí)的偏離量
第四個(gè)參數(shù)為樣式,博主選擇的是ROTATE情:線段連接處的圖形轉(zhuǎn)換以旋轉(zhuǎn)到與下一段移動(dòng)方向相一致的角度進(jìn)行連接。
最后使用ComposePathEffect進(jìn)行組合。
繪制運(yùn)動(dòng)路徑
private static Path makeFollowPath() { ? ? ? ? ? ? Path p = new Path(); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? p.lineTo(400,0); ? ? ? ? ? ? p.lineTo(400,400); ? ? ? ? ? ? p.lineTo(0,400); ? ? ? ? ? ? p.lineTo(0,0); ? ? ? ? ? ? return p; ? ? ? ? }
修改偏移量實(shí)現(xiàn)動(dòng)態(tài)效果
mPhase += 1; invalidate();
四、源碼
public class SampleView extends View { ? ? ? ? private Paint mPaint; ? ? ? ? private Path mPath; ? ? ? ? private PathEffect[] mEffects; ? ? ? ? private int mColors; ? ? ? ? private float mPhase; ? ? ? ? private static void makeEffects(PathEffect[] e, float phase) { ? ? ? ? ? ? e[0] = null; ? ?? ? ? ? ? ? ? e[1] = new CornerPathEffect(30); ? ? ? ? ? ? e[2] = new DashPathEffect(new float[] {10, 5, 5, 5}, phase); ? ? ? ? ? ? e[3] = new PathDashPathEffect(makePathDash(), 12, phase, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? PathDashPathEffect.Style.ROTATE); ? ? ? ? ? ? e[4] = new SumPathEffect(e[3], e[1]); ? ? ? ? ? ? e[5] = new ComposePathEffect(e[3], e[1]); ? ? ? ? } ? ? ? ? public SampleView(Context context) { ? ? ? ? ? ? super(context); ? ? ? ? ? ? setFocusable(true); ? ? ? ? ? ? setFocusableInTouchMode(true); ? ? ? ? ? ? mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); ? ? ? ? ? ? mPaint.setStyle(Paint.Style.STROKE); ? ? ? ? ? ? mPaint.setStrokeWidth(6); ? ? ? ? ? ? mPath = makeFollowPath(); ? ? ? ? ? ? //初始化PathEffect[] ? ? ? ? ? ? mEffects = new PathEffect[6]; ? ? ? ? ? ? mColors = Color.BLACK; ? ? ? ? } ? ? ? ? @Override ? ? ? ? protected void onDraw(Canvas canvas) { ? ? ? ? ? ? canvas.drawColor(Color.WHITE); ? ? ? ? ? ? RectF bounds = new RectF(); ? ? ? ? ? ? mPath.computeBounds(bounds, false); ? ? ? ? ? ? canvas.translate(10 - bounds.left, 10 - bounds.top); ? ? ? ? ? ? makeEffects(mEffects, mPhase); ? ? ? ? ? ? mPhase += 1; ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? //選擇樣式 ? ? ? ? ? ? mPaint.setPathEffect(mEffects[5]); ? ? ? ? ? ? mPaint.setColor(mColors); ? ? ? ? ? ? canvas.drawPath(mPath, mPaint); ? ? ? ? ? ? canvas.translate(0, 28); ? ? ? ? } ? ? ? ? @Override ? ? ? ? public boolean onKeyDown(int keyCode, KeyEvent event) { ? ? ? ? ? ? switch (keyCode) { ? ? ? ? ? ? ? ? case KeyEvent.KEYCODE_DPAD_CENTER: ? ? ? ? ? ? ? ? ? ? mPath = makeFollowPath(); ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? ? ? return super.onKeyDown(keyCode, event); ? ? ? ? } ? ? ? ? //繪制跑動(dòng)路徑 ? ? ? ? private static Path makeFollowPath() { ? ? ? ? ? ? Path p = new Path(); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? p.lineTo(400,0); ? ? ? ? ? ? p.lineTo(400,400); ? ? ? ? ? ? p.lineTo(0,400); ? ? ? ? ? ? p.lineTo(0,0); ? ? ? ? ? ? return p; ? ? ? ? } ? ? ? ? //繪制跑動(dòng)的小圖標(biāo) ? ? ? ? private static Path makePathDash() { ? ? ? ? ? ? Path p = new Path(); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? p.lineTo(4, 4); ? ? ? ? ? ? p.lineTo(8, 0); ? ? ? ? ? ? p.lineTo(4, -4); ? ? ? ? ? ? p.moveTo(0, 0); ? ? ? ? ? ? return p; ? ? ? ? } ? ? }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Android TabHost的多種實(shí)現(xiàn)方法 附源碼下載
這篇文章主要為大家詳細(xì)介紹了Android TabHost的多種實(shí)現(xiàn)方法 文章中針對(duì)每一種實(shí)現(xiàn)方法都附有源碼進(jìn)行下載,感興趣的小伙伴們可以參考一下2016-05-05Android5.0+ CollapsingToolbarLayout使用詳解
這篇文章主要為大家詳細(xì)介紹了Android5.0+ CollapsingToolbarLayout使用,感興趣的小伙伴們可以參考一下2016-09-09Android中RecyclerView實(shí)現(xiàn)多級(jí)折疊列表效果(二)
這篇文章主要給大家介紹了Android中RecyclerView實(shí)現(xiàn)多級(jí)折疊列表的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05React-Native Android 與 IOS App使用一份代碼實(shí)現(xiàn)方法
這篇文章主要介紹了React-Native Android 與 IOS App使用一份代碼實(shí)現(xiàn)方法的相關(guān)資料,這里舉例說(shuō)明,該如何實(shí)現(xiàn)IOS和Android APP 都使用一樣的代碼,需要的朋友可以參考下2016-12-12Flutter持久化存儲(chǔ)之?dāng)?shù)據(jù)庫(kù)存儲(chǔ)(sqflite)詳解
這篇文章主要給大家介紹了關(guān)于Flutter持久化存儲(chǔ)之?dāng)?shù)據(jù)庫(kù)存儲(chǔ)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Flutter 用自定義轉(zhuǎn)場(chǎng)動(dòng)畫實(shí)現(xiàn)頁(yè)面切換
本篇介紹了 fluro 導(dǎo)航到其他頁(yè)面的自定義轉(zhuǎn)場(chǎng)動(dòng)畫實(shí)現(xiàn),F(xiàn)lutter本身提供了不少預(yù)定義的轉(zhuǎn)場(chǎng)動(dòng)畫,可以通過(guò) transitionBuilder 參數(shù)設(shè)計(jì)多種多樣的轉(zhuǎn)場(chǎng)動(dòng)畫,也可以通過(guò)自定義的 AnimatedWidget實(shí)現(xiàn)個(gè)性化的轉(zhuǎn)場(chǎng)動(dòng)畫效果。2021-06-06Android高仿2048小游戲?qū)崿F(xiàn)代碼
這篇文章主要介紹了Android高仿2048小游戲?qū)崿F(xiàn)代碼的相關(guān)資料,非常不錯(cuò)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10