国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android自定義View系列之Path繪制仿支付寶支付成功動畫

2019-12-12 04:21:37
字體:
供稿:網(wǎng)友

前言

使用支付寶付款時,我們可以看到成功或者失敗都會有個動畫提示,如果我們需要做這樣的效果的話,當然,你可以讓設計師給你做個GIF,但是我們知道圖像比較耗內(nèi)存的,我們自己可以用代碼實現(xiàn)還是代碼實現(xiàn)好點吧。

效果

實現(xiàn)方法

首先我們需要了解PathMeasure這個類,這個類我們可以理解為用來管理Path。我們主要看幾個方法。

PathMeasure(): 構(gòu)造方法 ,實例化一個對象

PathMeasure(Path path,boolean isClosed):傳入Path對象和是否閉合,path對象不能為空

getLength():獲取當前輪廓、外形的總長度, 如果沒有設置Path對象,返回0

getSegment(float startD,float stopD,Path dst,boolean startWithMoveTo):調(diào)用這個方法,我們可以獲取到指定范圍內(nèi)的一段輪廓,存入到dst參數(shù)中。所以,這個方法傳入的參數(shù)分別為長度起始值、結(jié)束值、裝這一段路徑的Path對象、是否MoveTo。另外,這個方法返回值為Boolean類型,如果getLength為0的話,返回false,或者startD > stopD,同樣返回false。

setPath(Path path , boolean isClosed):給當前PathMeasure對象設置Path

nextContour():移動到下一個輪廓

然后我們需要動起來,我們知道invalidate()方法可以刷新界面,也就是重新調(diào)用onDraw()方法,所以我們要不停調(diào)用invalidate方法,在onDraw方法中改變參數(shù),這樣實現(xiàn)動的效果。所以可以用到剛剛介紹的getSegment方法,不斷改變獲取的范圍,從0 * getLength,到1 * getLength,最后繪制完整。所以我們需要一個在一秒內(nèi)或兩秒內(nèi)一個從0到1的值的變化,so,我們使用ValueAnimator這個類來實現(xiàn)。

//實例化對象mCircleAnimator = ValueAnimator.ofFloat(0, 1);//設置時長為1000msmCircleAnimator.setDuration(1000);//開始動畫mCircleAnimator.start();//設置動畫監(jiān)聽mCircleAnimator.addUpdateListener(this);

動畫開始后,在監(jiān)聽方法中獲取當前進度并且重繪圖像

mCirclePercent = (float)animation.getAnimatedValue();invalidate();

在onDraw方法中,繪制圖像

//畫圓mPathCircle.addCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - mLineWidth, Path.Direction.CW);mPathMeasure.setPath(mPathCircle, false);mPathMeasure.getSegment(0, mCirclePercent * mPathMeasure.getLength(), mPathCircleDst, true);canvas.drawPath(mPathCircleDst, mPaint);

附上源碼,歡迎點評

package com.mintmedical.wavedemo;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PathMeasure;import android.util.AttributeSet;import android.util.Log;import android.view.View;/** * Created by MooreLi on 2016/12/12. */public class ResultAnimation extends View implements ValueAnimator.AnimatorUpdateListener { private Context mContext; /**  * paint對象  */ private Paint mPaint; /**  * Path和對應的空Path用來填充  */ private Path mPathCircle; private Path mPathCircleDst; private Path mPathRight; private Path mPathRightDst; private Path mPathWrong1; private Path mPathWrong2; private Path mPathWrong1Dst; private Path mPathWrong2Dst; /**  * Path管理  */ private PathMeasure mPathMeasure; /**  * 動畫  */ private ValueAnimator mCircleAnimator; private ValueAnimator mRightAnimator; private ValueAnimator mWrong1Animator; private ValueAnimator mWrong2Animator; /**  * 當前繪制進度占總Path長度百分比  */ private float mCirclePercent; private float mRightPercent; private float mWrong1Percent; private float mWrong2Percent; /**  * 線寬  */ private int mLineWidth; /**  * 正確動畫 錯誤動畫  */ public static final int RESULT_RIGHT = 1; public static final int RESULT_WRONG = 2; /**  * 當前結(jié)果類型  */ private int mResultType = RESULT_WRONG; public ResultAnimation(Context context) {  super(context);  mContext = context;  init(); } public ResultAnimation(Context context, AttributeSet attrs) {  super(context, attrs);  mContext = context;  init(); } public ResultAnimation(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  mContext = context;  init(); } private void init() {  mLineWidth = dp2px(3);  mPaint = new Paint();  mPaint.setAntiAlias(true);  mPaint.setStrokeWidth(mLineWidth);  mPaint.setStyle(Paint.Style.STROKE);  mPaint.setColor(Color.GREEN);  initPath(); } private void initPath() {  mPathCircle = new Path();  mPathCircleDst = new Path();  mPathRight = new Path();  mPathRightDst = new Path();  mPathWrong1 = new Path();  mPathWrong2 = new Path();  mPathWrong1Dst = new Path();  mPathWrong2Dst = new Path();  mPathMeasure = new PathMeasure();  //實例化對象  mCircleAnimator = ValueAnimator.ofFloat(0, 1);  //設置時長為1000ms  mCircleAnimator.setDuration(1000);  //開始動畫  mCircleAnimator.start();  //設置動畫監(jiān)聽  mCircleAnimator.addUpdateListener(this);  mRightAnimator = ValueAnimator.ofFloat(0, 1);  mRightAnimator.setDuration(500);  mRightAnimator.addUpdateListener(this);  mWrong1Animator = ValueAnimator.ofFloat(0, 1);  mWrong1Animator.setDuration(300);  mWrong1Animator.addUpdateListener(this);  mWrong2Animator = ValueAnimator.ofFloat(0, 1);  mWrong2Animator.setDuration(300);  mWrong2Animator.addUpdateListener(this); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  if (mResultType == RESULT_RIGHT) {   mPaint.setColor(Color.GREEN);  } else {   mPaint.setColor(Color.RED);  }  //畫圓  mPathCircle.addCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - mLineWidth, Path.Direction.CW);  mPathMeasure.setPath(mPathCircle, false);  mPathMeasure.getSegment(0, mCirclePercent * mPathMeasure.getLength(), mPathCircleDst, true);  canvas.drawPath(mPathCircleDst, mPaint);  if (mResultType == RESULT_RIGHT) {   //畫對勾   mPathRight.moveTo(getWidth() / 4, getWidth() / 2);   mPathRight.lineTo(getWidth() / 2, getWidth() / 4 * 3);   mPathRight.lineTo(getWidth() / 4 * 3, getWidth() / 4);   if (mCirclePercent == 1) {    mPathMeasure.nextContour();    mPathMeasure.setPath(mPathRight, false);    mPathMeasure.getSegment(0, mRightPercent * mPathMeasure.getLength(), mPathRightDst, true);    canvas.drawPath(mPathRightDst, mPaint);   }  } else {   mPathWrong1.moveTo(getWidth() / 4 * 3, getWidth() / 4);   mPathWrong1.lineTo(getWidth() / 4, getWidth() / 4 * 3);   mPathWrong2.moveTo(getWidth() / 4, getWidth() / 4);   mPathWrong2.lineTo(getWidth() / 4 * 3, getWidth() / 4 * 3);   if (mCirclePercent == 1) {    mPathMeasure.nextContour();    mPathMeasure.setPath(mPathWrong1, false);    mPathMeasure.getSegment(0, mWrong1Percent * mPathMeasure.getLength(), mPathWrong1Dst, true);    canvas.drawPath(mPathWrong1Dst, mPaint);   }   if (mWrong1Percent == 1) {    mPathMeasure.nextContour();    mPathMeasure.setPath(mPathWrong2, false);    mPathMeasure.getSegment(0, mWrong2Percent * mPathMeasure.getLength(), mPathWrong2Dst, true);    canvas.drawPath(mPathWrong2Dst, mPaint);   }  } } private int dp2px(int dp) {  float scale = mContext.getResources().getDisplayMetrics().density;  return (int) (scale * dp + 0.5f); } @Override public void onAnimationUpdate(ValueAnimator animation) {  //圓形動畫  if (animation.equals(mCircleAnimator)) {   mCirclePercent = (float) animation.getAnimatedValue();   invalidate();   Log.e("TEST","percent:"+mCirclePercent);   if (mCirclePercent == 1) {    if (mResultType == RESULT_RIGHT)     mRightAnimator.start();    else     mWrong1Animator.start();   }  }  //正確時 對勾動畫  else if (animation.equals(mRightAnimator)) {   mRightPercent = (float) animation.getAnimatedValue();   invalidate();  }  //錯誤時 右側(cè)動畫  else if (animation.equals(mWrong1Animator)) {   mWrong1Percent = (float) animation.getAnimatedValue();   invalidate();   if (mWrong1Percent == 1) {    mWrong2Animator.start();   }  }  //錯誤時 左側(cè)動畫  else if (animation.equals(mWrong2Animator)) {   mWrong2Percent = (float) animation.getAnimatedValue();   invalidate();  } } public void setmResultType(int mResultType) {  this.mResultType = mResultType;  invalidate(); } /**  * 固定寫死了寬高,可重新手動調(diào)配  *  * @param widthMeasureSpec  * @param heightMeasureSpec  */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  setMeasuredDimension(dp2px(50), dp2px(50)); }}

github地址: https://github.com/lizebinbin

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 思南县| 天津市| 成武县| 新乡市| 耿马| 哈尔滨市| 定陶县| 永年县| 遂溪县| 清河县| 额济纳旗| 黎川县| 太谷县| 吉木乃县| 万山特区| 甘泉县| 上栗县| 鄱阳县| 无棣县| 永寿县| 会昌县| 和顺县| 库伦旗| 永仁县| 江城| 黄冈市| 上高县| 含山县| 门头沟区| 汽车| 开原市| 焦作市| 阳信县| 邵武市| 泗水县| 庆元县| 望奎县| 卓尼县| 新民市| 泸水县| 静安区|