(笔记)自定义Progress 动画 ProgressView

来源:互联网 发布:floyed最短路径算法 编辑:程序博客网 时间:2024/05/16 11:21
http://blog.csdn.net/q649381130/article/details/51700902
import android.animation.ValueAnimator;import android.animation.ValueAnimator.AnimatorUpdateListener;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import android.view.animation.LinearInterpolator;import com.ema.control.R;public class ProgressView extends View{    private int mDotCount = 5; // 圆点个数    private int mDotColor = 0xFFFF9966;// 圆点颜色    private Paint mPaint;    private int mRingRadius = 50;// 圆环半径,单位dp    private int mOriginalRingRadius;// 保存的原始圆环半径,单位dp    private int mDotRadius = 7; // 小点半径,单位dp    private int mOriginalDotRadius; // 保存的原始小点半径,单位dp    private int mCurrentAngle = 0; // 当前旋转的角度    private ValueAnimator mAnimator;// 旋转动画    public ProgressView(Context context, AttributeSet attrs, int defStyleAttr)    {        super(context, attrs, defStyleAttr);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);        mDotColor = ta.getColor(R.styleable.ProgressView_dot_color, mDotColor);        mDotCount = ta.getInt(R.styleable.ProgressView_dot_count, mDotCount);        ta.recycle();        init();    }    public ProgressView(Context context, AttributeSet attrs)    {        this(context, attrs, 0);    }    public ProgressView(Context context)    {        this(context, null);    }    private void init()    {        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setStyle(Style.FILL_AND_STROKE);        mPaint.setColor(mDotColor);        // 屏幕适配,转化圆环半径,小点半径        mRingRadius = dp2px(getContext(), mRingRadius);        mDotRadius = dp2px(getContext(), mDotRadius);        mOriginalDotRadius = mDotRadius;        initAnimatior();    }    public int dp2px(Context context, float dp)    {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources()                .getDisplayMetrics());    }    private void initAnimatior()    {        mAnimator = ValueAnimator.ofInt(0, 359);        mAnimator.setDuration(4000);        mAnimator.setRepeatCount(-1);        mAnimator.setRepeatMode(ValueAnimator.INFINITE);        mAnimator.setInterpolator(new LinearInterpolator());        mAnimator.addUpdateListener(new AnimatorUpdateListener()        {            @Override            public void onAnimationUpdate(ValueAnimator animation)            {                mCurrentAngle = (int) animation.getAnimatedValue();                invalidate();            }        });    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom)    {        super.onLayout(changed, left, top, right, bottom);        // 重设圆环半径,防止超出视图大小        int effectiveWidth = getWidth() - getPaddingLeft() - getPaddingRight();        int effectiveHeight = getHeight() - getPaddingBottom() - getPaddingTop();        int maxRadius = Math.min(effectiveWidth / 2, effectiveHeight / 2) - mDotRadius;        mRingRadius = mRingRadius > maxRadius ? maxRadius : mRingRadius;        mOriginalRingRadius = mRingRadius;    }    @Override    protected void onDraw(Canvas canvas)    {        // 根据小球总数平均分配整个圆,得到每个小球的间隔角度        double cellAngle = 360 / mDotCount;        for (int i = 0; i < mDotCount; i++) {            double ange = i * cellAngle + mCurrentAngle;            // 根据当前角度计算小球到圆心的距离            calculateRadiusFromProgress();            // 根据角度绘制单个小球            drawDot(canvas, ange * 2 * Math.PI / 360);        }    }    /**     * 根据当前旋转角度计算mRingRadius、mDotRadius的值     * mCurrentAngle:   0 - 180 - 360     * mRingRadius:     最小 - 最大 - 最小     *     * @author 漆可     * @date 2016-6-17 下午3:04:35     */    private void calculateRadiusFromProgress()    {        float fraction = 1.0f * mCurrentAngle / 180 - 1;        fraction = Math.abs(fraction);        mRingRadius = evaluate(fraction, mOriginalRingRadius, mOriginalRingRadius * 2 / 4);        mDotRadius = evaluate(fraction, mOriginalDotRadius, mOriginalDotRadius * 4 / 5);    }    // fraction:当前的估值器计算值,startValue:起始值,endValue:终点值    private Integer evaluate(float fraction, Integer startValue, Integer endValue)    {        return (int) (startValue + fraction * (endValue - startValue));    }    @Override    protected void onAttachedToWindow()    {        super.onAttachedToWindow();        startAnimation();    }    private void drawDot(Canvas canvas, double angle)    {        // 根据当前角度获取x、y坐标点        float x = (float) (getWidth() / 2 + mRingRadius * Math.sin(angle));        float y = (float) (getHeight() / 2 - mRingRadius * Math.cos(angle));        // 绘制圆        canvas.drawCircle(x, y, mDotRadius, mPaint);    }    public void startAnimation()    {        mAnimator.start();    }    public void stopAnimation()    {        mAnimator.end();    }    //销毁页面时停止动画    @Override    protected void onDetachedFromWindow()    {        super.onDetachedFromWindow();        stopAnimation();    }}

原创粉丝点击