android 仿直播中的圆点加载效果

今天实现一个很多app中使用到的加载进度条的效果,可能我们平时数据加载都使用到的是系统自带的,但是也有很多app加载进度条的效果实现挺好看,就是三个点不停的水平跑而且是变换颜色的,其实这个效果很简单,

分析:

第一步:

android 仿直播中的圆点加载效果_第1张图片

第二步:

android 仿直播中的圆点加载效果_第2张图片

为了圆的颜色 大小,以及移动的距离都对外开放,采用了自定义属性的方式,当然也可以进行设置,

分析了后 代码就直接上了,

xml version="1.0" encoding="utf-8"?>

    name="CirclePointLoadView">
        name="leftPointColor" format="color|reference">
        name="middlePointColor" format="color|reference">
        name="rightPointColor" format="color|reference">
        name="radius" format="integer|reference">
        name="translationDistance" format="dimension|reference">
    

这是自定义属性,左,中,右颜色,圆的半径,以及圆x轴移动的距离

CircleItemPointView.java

是每个子view的代码,很简单就是画了圆,然后设置了下paint的颜色而已

package com.circle.load;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by zhouguizhijxhz on 2018/5/29.
 */
public class CircleItemPointView  extends View {
    private Paint mPaint;
    private int mColor;
    public CircleItemPointView(Context context) {
        this(context,null);
    }

    public CircleItemPointView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleItemPointView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int cx = getWidth()/2;
        int cy = getHeight()/2;
        canvas.drawCircle(cx,cy,cx,mPaint);
    }
    /**
     * 切换颜色
     */
    public void changeColor(int color){
        mColor = color;
        mPaint.setColor(color);
        invalidate();
    }
    public void setColor(int color){
        mColor = color;
        mPaint.setColor(color);
        invalidate();
    }
    /**
     * 获取当前的颜色
     */
    public int getColor() {
        return mColor;
    }
}

CirclePointLoadView.java

package com.circle.load;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.RelativeLayout;
/**
 * Created by zhouguizhijxhz on 2018/5/29.
 */
public class CirclePointLoadView extends RelativeLayout{
    private int defaultLeftColor = Color.parseColor("#FF8247");
    private int defaultMiddleColor = Color.parseColor("#EE4000");
    private int defaultRightColor = Color.parseColor("#CD2626");
    private int leftColor;
    private int middleColor;
    private int rightColor;
    private int defaultCircleRadius = 10;
    private int defaultTranslationDistance = 36;
    private int translationDistance;
    private static final long ANIMATION_DURATION = 400;
    private int radius;
    private CircleItemPointView leftView;
    private CircleItemPointView middleView;
    private CircleItemPointView rightView;
    private AnimatorSet spreadAnimation;
    private AnimatorSet closedAnimation;
    public CirclePointLoadView(Context context) {
        this(context,null);
    }
    public CirclePointLoadView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public CirclePointLoadView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        parseAttrs(context,attrs);
        addViewToLayout(context);
    }

    private void addViewToLayout(Context context) {
        if(null==context){
            return;
        }
        leftView = createView(context);
        leftView.setColor(leftColor);
        middleView = createView(context);
        middleView.setColor(middleColor);
        rightView = createView(context);
        rightView.setColor(rightColor);
        addView(leftView);
        addView(rightView);
        addView(middleView);
    }
    /**
     * 展开动画
     */
    private void spreadAnimation() {
        ObjectAnimator leftTranslationAnimator = ObjectAnimator.ofFloat(leftView,"translationX",0,-translationDistance);
        ObjectAnimator rightTranslationAnimator = ObjectAnimator.ofFloat(rightView,"translationX",0,translationDistance);
        spreadAnimation = new AnimatorSet();
        spreadAnimation.setDuration(ANIMATION_DURATION);
        spreadAnimation.playTogether(leftTranslationAnimator,rightTranslationAnimator);
        spreadAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                closedAnimation();
            }
        });
        spreadAnimation.start();
    }

    private void closedAnimation() {
        ObjectAnimator leftTranslationAnimator = ObjectAnimator.ofFloat(leftView,"translationX",-translationDistance,0);
        ObjectAnimator rightTranslationAnimator = ObjectAnimator.ofFloat(rightView,"translationX",translationDistance,0);
        closedAnimation = new AnimatorSet();
        closedAnimation.setInterpolator(new AccelerateInterpolator());
        closedAnimation.setDuration(ANIMATION_DURATION);
        closedAnimation.playTogether(leftTranslationAnimator,rightTranslationAnimator);
        closedAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                int leftColor = leftView.getColor();
                int rightColor = rightView.getColor();
                int middleColor = middleView.getColor();
                middleView.changeColor(leftColor);
                rightView.changeColor(middleColor);
                leftView.changeColor(rightColor);
                spreadAnimation();
            }
        });
        closedAnimation.start();
    }
    public CircleItemPointView createView(Context context) {
        CircleItemPointView itemPointView = new CircleItemPointView(context);
        LayoutParams params = new LayoutParams(DensityUtils.dp2px(context,radius),DensityUtils.dp2px(context,radius));
        params.addRule(CENTER_IN_PARENT);
        itemPointView.setLayoutParams(params);
        return itemPointView;
    }
    private void parseAttrs(Context context, AttributeSet attrs) {
        if(null==context||null==attrs){
            return;
        }
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.CirclePointLoadView);
        leftColor =  typedArray.getColor(R.styleable.CirclePointLoadView_leftPointColor,defaultLeftColor);
        middleColor =  typedArray.getColor(R.styleable.CirclePointLoadView_middlePointColor,defaultMiddleColor);
        rightColor =  typedArray.getColor(R.styleable.CirclePointLoadView_rightPointColor,defaultRightColor);
        radius = typedArray.getInteger(R.styleable.CirclePointLoadView_radius,defaultCircleRadius);
        translationDistance = (int) typedArray.getDimension(R.styleable.CirclePointLoadView_translationDistance,defaultTranslationDistance);
        translationDistance = DensityUtils.dp2px(context,translationDistance);
        typedArray.recycle();
    }

    /**
     * 开启动画
     */
    public void startLoad(){
        if(spreadAnimation==null){
            spreadAnimation();
        }
    }
    /**
     * 停止动画
     */
    public void stopLoad(){
        clearAnimation();
        leftView.setVisibility(View.GONE);
        middleView.setVisibility(View.GONE);
        rightView.setVisibility(View.GONE);
    }

    /**
     * 设置左侧颜色值
     * @param leftColor
     */
    public void setLeftColor(int leftColor) {
        this.leftColor = leftColor;
    }
    /**
     * 设置中间颜色值
     * @param middleColor
     */
    public void setMiddleColor(int middleColor) {
        this.middleColor = middleColor;
    }
    /**
     * 设置右侧颜色值
     * @param rightColor
     */
    public void setRightColor(int rightColor) {
        this.rightColor = rightColor;
    }
    /**
     * 设置圆的半径
     * @param radius
     */
    public void setRadius(int radius) {
        this.radius = radius;
    }
    /**
     * 设置动画x轴方向移动的距离
     * @param translationDistance
     */
    public void setTranslationDistance(int translationDistance) {
        translationDistance = translationDistance;
    }
}

效果图:

android 仿直播中的圆点加载效果_第3张图片

你可能感兴趣的:(自定义控件)