日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对号动画实现

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对号动画实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作為菜逼,第一次嘗試做動畫。動畫的需求是模仿支付寶付款驗密成功的對號動畫。

主View的代碼:

package gt.research.test.androidtest;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; import android.widget.ImageView;public class TickView extends ImageView {public static final int FRAME = 16;public static final int INIT = 0;public static final int DIRTY = 1;public static final int DRAWN = 2;public static final int DONE = 3;//ppi relatedprivate static final int sMARGIN = 5;private Paint mPaint;private float mMiddleX;private float mStartX;private float mEndX;private float mBaseY;private int mOffset;private int mTickPaddingLeft;private int mTickPaddingRight;private int mTickPaddingBottom;private static final int sDEFAULT_COLOR = Color.parseColor("#00307f");private static final int sDEFAULT_STROCK = 10;private static int sDEFAULT_DURATION = 100;private static int sDEFAULT_PADDING = 20;private volatile float mX;private volatile float mY;private float mB0;private float mB1;private float mStep;private long mDuration;private long mDelay = FRAME;private volatile int mState = INIT;private Handler mHandler;private volatile Rect mDirty;private Runnable mPostInvalidate = new Runnable() {@Overridepublic void run() {if (DRAWN == mState) {mDirty = getDirtyRect(mX, mY);if (null == mDirty) {mState = DONE;return;}invalidate(mDirty);}if (INIT == mState || DRAWN == mState || DIRTY == mState) {mHandler.removeCallbacks(mPostInvalidate);mHandler.postDelayed(mPostInvalidate, mDelay);if (DRAWN == mState) {mState = DIRTY;}}}};public TickView(Context context) {super(context);init(null, 0);}public TickView(Context context, AttributeSet attrs) {super(context, attrs);init(attrs, 0);}public TickView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(attrs, defStyle);}private void init(AttributeSet attrs, int defStyle) {mPaint = new Paint();TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TickView);mPaint.setColor(a.getColor(R.styleable.TickView_tickColor, sDEFAULT_COLOR));mPaint.setStrokeWidth(a.getDimensionPixelSize(R.styleable.TickView_strokeWidth, sDEFAULT_STROCK));mOffset = a.getDimensionPixelOffset(R.styleable.TickView_turnOffset, 0);mDuration = a.getInt(R.styleable.TickView_duration, sDEFAULT_DURATION);mTickPaddingLeft = a.getDimensionPixelSize(R.styleable.TickView_tickPaddingLeft, sDEFAULT_PADDING);mTickPaddingRight = a.getDimensionPixelSize(R.styleable.TickView_tickPaddingRight, sDEFAULT_PADDING);mTickPaddingBottom = a.getDimensionPixelSize(R.styleable.TickView_tickPaddingBottom, sDEFAULT_COLOR);mHandler = new Handler(Looper.getMainLooper());a.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mMiddleX = getMeasuredWidth() / 2 - mOffset;mX = mStartX = mTickPaddingLeft;mEndX = getMeasuredWidth() - mTickPaddingRight;mBaseY = getMeasuredHeight() - mTickPaddingBottom;mB0 = mBaseY - mMiddleX;mB1 = mBaseY + mMiddleX;mY = mX + mB0;mStep = (mEndX - mStartX) / (float) mDuration * FRAME;setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));}public void startAnimation() {mHandler.post(mPostInvalidate);mState = INIT;}@Overrideprotected void onDraw(Canvas canvas) {if (DONE == mState) {super.onDraw(canvas);drawTotal(canvas);return;}long start = System.currentTimeMillis();if (canvas.isHardwareAccelerated()) {super.onDraw(canvas);drawWhole(canvas);} else {if (null != mDirty) {canvas.clipRect(mDirty);}super.onDraw(canvas);drawPartial(canvas);}mState = DRAWN;long end = System.currentTimeMillis();mDelay = FRAME - end + start;mDelay = mDelay < 0 ? 0 : mDelay;}private void drawWhole(Canvas canvas) {if (mX + mStep < mMiddleX) {canvas.drawLine(mStartX, mStartX + mB0, mX + mStep + sMARGIN, mY + mStep + sMARGIN, mPaint);mX += mStep;mY += mStep;} else {canvas.drawLine(mStartX, mStartX + mB0, mMiddleX + sMARGIN, mBaseY + sMARGIN, mPaint);canvas.drawLine(mBaseY - mB0 - sMARGIN, mBaseY + sMARGIN, mX + sMARGIN, mB1 - mX - sMARGIN, mPaint);mX += mStep;mY -= mStep;}}private void drawPartial(Canvas canvas) {if (mX + mStep < mMiddleX) {canvas.drawLine(mX - sMARGIN, mY - sMARGIN, mX + mStep + sMARGIN, mY + mStep + sMARGIN, mPaint);mX += mStep;mY += mStep;} else if (mX > mMiddleX) {canvas.drawLine(mX - sMARGIN, mY + sMARGIN, mX + mStep + sMARGIN, mY - mStep - sMARGIN, mPaint);mX += mStep;mY -= mStep;} else {canvas.drawLine(mX - sMARGIN, mY - sMARGIN, mBaseY - mB0 + sMARGIN, mBaseY + sMARGIN, mPaint);canvas.drawLine(mBaseY - mB0 - sMARGIN, mBaseY + sMARGIN, mX + mStep + sMARGIN, mB1 - mX - mStep - sMARGIN, mPaint);mX += mStep;mY = mB1 - mX;}}private void drawTotal(Canvas canvas) {canvas.drawLine(mStartX, mStartX + mB0, mMiddleX + sMARGIN, mBaseY + sMARGIN, mPaint);canvas.drawLine(mBaseY - mB0 - sMARGIN, mBaseY + sMARGIN, mEndX, mB1 - mEndX, mPaint);}private Rect getDirtyRect(float x, float y) {if (x >= mEndX) {return null;}Rect rect = new Rect();if (x + mStep < mMiddleX) {rect.left = (int) x - sMARGIN;rect.right = (int) (x + mStep) + sMARGIN;rect.top = (int) y - sMARGIN;rect.bottom = (int) (y + mStep) + sMARGIN;} else if (x > mMiddleX) {rect.left = (int) x - sMARGIN;rect.right = (int) (x + mStep) + sMARGIN;rect.top = (int) (y - mStep) - sMARGIN;rect.bottom = (int) y + sMARGIN;} else {rect.left = (int) x - sMARGIN;rect.right = (int) (x + mStep) + sMARGIN;rect.top = (int) Math.min(y, mB1 - x - mStep) - sMARGIN;rect.bottom = (int) mBaseY + sMARGIN;}return rect;} }

大體思路是,外圍圓圈是背景圖片,中間對勾使用drawLine漸變繪出。
有幾個坑:
- 硬件加速的View不會對某塊DirtyRect重繪,而是全局重繪參考
- draw時使用的是int,需要在轉化時加上margin,避免強轉時露點。margin與ppi相關,基本xhdpi就是1,xx是2
- onDraw時postInvalidate貌似不能用

總結

以上是生活随笔為你收集整理的对号动画实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。