美文网首页Android开发常用代码
自定义view之百度加载效果

自定义view之百度加载效果

作者: 才兄说 | 来源:发表于2017-06-11 20:34 被阅读15次

xml

<com.jianshu.LoadCircleView
    android:id="@+id/circle"
    android:layout_width="wrap_content"
    android:layout_height="100dp"
    app:circle_radius="10"
    app:duration="800" />

colors.xml

<color name="color_red">#EA4346</color>
<color name="color_black">#646363</color>
<color name="color_blue">#3789F9</color>

attrs.xml

<declare-styleable name="LoadCircleView">
    <!--圆的半径-->
    <attr name="circle_radius" format="float" />
    <!--持续时间-->
    <attr name="duration" format="integer" />
</declare-styleable>

自定义view:

public class LoadCircleView extends View {
    /**
     * 第一个动画的索引
     */
    private int changeIndex = 0;
    /**
     * 圆的颜色值
     */
    private int[] colors = new int[]{
            getResources().getColor(R.color.color_red),
            getResources().getColor(R.color.color_blue),
            getResources().getColor(R.color.color_black)};
    /**
     * 偏移量
     */
    private Float maxWidth = 50f;
    /**
     * 圆的半径 默认10f
     */
    private Float circleRadius = 10f;
    /**
     * 当前偏移的X坐标
     */
    private Float currentX = 0f;
    /**
     * 画笔
     */
    private Paint paint;
    /**
     * 属性动画
     */
    private ValueAnimator valueAnimator;
    /**
     * 持续时间
     */
    private int duration = 800;

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

    public LoadCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LoadCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        if (null != attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadCircleView);
            circleRadius = typedArray.getFloat(R.styleable.LoadCircleView_circle_radius, circleRadius);
            duration = typedArray.getInt(R.styleable.LoadCircleView_duration, duration);
            typedArray.recycle();//记得回收
        }
        startAnimator();
    }

    /**
     * 位移动画
     */
    private void startAnimator() {
        valueAnimator = ValueAnimator.ofFloat(0f, maxWidth, 0);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                currentX = (Float) animation.getAnimatedValue();
                invalidate();//执行刷新onDraw()
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                changePoint(changeIndex);
            }
        });
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setRepeatCount(-1);
        valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
        valueAnimator.setDuration(duration);
        valueAnimator.start();
    }

    /**
     * 先执行动画的目标和中间停止的动画目标交换
     * (颜色切换)
     *
     * @param index 最先执行的动画的索引
     */
    private void changePoint(int index) {
        int temp = colors[2];
        colors[2] = colors[index];
        colors[index] = temp;
        changeIndex = (index == 0) ? 1 : 0;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        /**左边圆**/
        paint.setColor(colors[0]);
        canvas.drawCircle(centerX - currentX, centerY, circleRadius, paint);
        /**右边圆**/
        paint.setColor(colors[1]);
        canvas.drawCircle(centerX + currentX, centerY, circleRadius, paint);
        /**中间圆**/
        paint.setColor(colors[2]);
        canvas.drawCircle(centerX, centerY, circleRadius, paint);
    }

    //销毁View的时候回调
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        valueAnimator.cancel();
    }
}

相关文章

网友评论

    本文标题:自定义view之百度加载效果

    本文链接:https://www.haomeiwen.com/subject/jkqkqxtx.html