PathMeasure實現自定義圓形ProgressBar

先上效果圖

實現原理

其實這種不規則的動畫,以及支付寶的支付成功動畫,實現原理都差不多,首先就是利用Path畫出完成的圖案路徑,然後利用PathMeasure測量出路徑的長度,然後PathMeasure截取出Path的片段,再結合屬性動畫,截取出時間上連續的Path路徑,然後繪製出path就完成了,代碼很簡單,主要是這種思想,可以實現各種各樣的炫酷的小動畫。

代碼實現

public class MyProgress extends View {
    private Context mContext;
    private Paint mPaint;
    private Path mPath;
    private PathMeasure mPathMeasure;
    private float mLength;
    private float mAnimatorValue;
    private Path dst;

    public MyProgress(Context context) {
        this(context, null);
    }

    public MyProgress(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        init();
    }

    private void init() {
        //畫筆
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.parseColor("#FF4081"));
        mPaint.setStrokeWidth(10f);
        mPaint.setStyle(Paint.Style.STROKE);
        //Path
        dst = new Path();
        mPath = new Path();

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mPath.addCircle(getWidth()/2, getWidth()/2, getWidth()/4, Path.Direction.CW);//加入一個半徑爲100圓

        mPathMeasure = new PathMeasure(mPath, true);
        mLength = mPathMeasure.getLength();

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.addUpdateListener(animation -> {
            mAnimatorValue = (float) animation.getAnimatedValue();
            invalidate();
        });
        animator.setDuration(2000);
        animator.setRepeatCount(ValueAnimator.INFINITE);//無限循環
        animator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        dst.reset();
        float distance = mLength * mAnimatorValue;
//        distance     start  disant -0
        float start = (float) (distance - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * mLength));
//   ( distance-0.5*mLength)   start   distance
//mPath  1  dst  2
        mPathMeasure.getSegment(start, distance, dst, true);
        canvas.drawPath(dst, mPaint);
    }
}

使用就很簡單了


public class ProgressActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyProgress(this));
    }
}

Demo地址:https://github.com/987570437/WangYiMusicAnimDemo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章