自定义控件,

大神勿喷,菜鸟互相学习!!

首先上效果图:


自定义控件,



这里你要清楚这个自定义控件的步骤:

1、首先画上静态的圆环和未选中的购。

2、当点击控件不画之前的静态图,其次启动一个画粉色圆弧的动画。圆弧画满后设置FILL充满颜色。

3、圆弧画满后启动一个花白色的圆。圆的半径逐渐变成0、

4、白色圆变成0后,粉色启动一个半径变大再缩小,形成一个放大效果

5、然后画路径,这里我调皮了下,其实是画选择的沟。


好了思路清晰了,上代码:

/**
 * Created by lihang on 2017/11/22.
 */

public class TickView extends View {

    private AnimatorSet animatorSet = new AnimatorSet();

    private Paint paint;//画圆弧的画笔
    private Paint oKpaint;//画勾的画笔

    private Paint circlePaint;//白色的圆
    private int radius = 80;


    private RectF mRectF = new RectF();
    //控件中心的X,Y坐标
    private int centerX;
    private int centerY;

    //绘制勾的路径
    private Path path = new Path();

    //绘制李字路径
    private Path pathLeo = new Path();

    private PathMeasure pathMeasure;
    private DashPathEffect effect;



    /**
     * 设置画圆动画
     */
    private ValueAnimator animator_circle;
    private int currentProgress;

    private boolean isStart;
    private int whiteRadius = -1;
    private ValueAnimator animator_white;

    private int scaceRadius = 100;
    private ValueAnimator animator_scace;


    private ValueAnimator animator_line;
    private boolean startLine;


    private ClickAndAnim listener;

    public ClickAndAnim getListener() {
        return listener;
    }

    public void setListener(ClickAndAnim listener) {
        this.listener = listener;
    }



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

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

    public TickView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initPaint();
        initAnim();
        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    listener.onClickListener();
                }
            }
        });



        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (listener != null) {
                    listener.onAnimFish();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });


    }


    //初始化动画
    private void initAnim() {

        animator_circle = ValueAnimator.ofInt(0, 360);
        animator_circle.setDuration(600);
        animator_circle.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                isStart = true;
                paint.setColor(getResources().getColor(R.color.pink));
                currentProgress = (int) valueAnimator.getAnimatedValue();
                postInvalidate();
            }
        });


        animator_white = ValueAnimator.ofInt(radius - 5, 0);
        animator_white.setDuration(400);
        animator_white.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                whiteRadius = (int) valueAnimator.getAnimatedValue();
                postInvalidate();
            }
        });




        animator_scace = ValueAnimator.ofInt(radius,radius+50,radius);
        animator_scace.setDuration(600);
        animator_scace.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                scaceRadius = (int) valueAnimator.getAnimatedValue();
                postInvalidate();
            }
        });


        animator_line = ValueAnimator.ofFloat(1, 0);
        animator_line.setDuration(1000);
        animator_line.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                startLine = true;
                float value = (Float) animation.getAnimatedValue();

                effect = new DashPathEffect(new float[]{pathMeasure.getLength(), pathMeasure.getLength()}, value * pathMeasure.getLength());
                oKpaint.setPathEffect(effect);
                postInvalidate();

            }
        });

    }

    private void initPaint() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(dp2px(2));
        paint.setColor(getResources().getColor(R.color.grey));


        oKpaint = new Paint();
        oKpaint.setAntiAlias(true);
        oKpaint.setStyle(Paint.Style.STROKE);
        oKpaint.setStrokeWidth(dp2px(2));
        oKpaint.setColor(getResources().getColor(R.color.grey));


        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);
        circlePaint.setStyle(Paint.Style.FILL);
        circlePaint.setStrokeWidth(dp2px(2));
        circlePaint.setColor(Color.WHITE);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //设置圆圈的外切矩形

        centerX = getMeasuredWidth() / 2;
        centerY = getMeasuredHeight() / 2;
        mRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);

        path.moveTo(getMeasuredHeight() / 8 * 3, getMeasuredHeight() / 2);
        path.lineTo(getMeasuredHeight() / 2, getMeasuredHeight() / 5 * 3);
        path.lineTo(getMeasuredHeight() / 3 * 2, getMeasuredHeight() / 5 * 2);


        pathLeo.moveTo(getMeasuredWidth()/2-55,getMeasuredHeight()/2-50);
        pathLeo.lineTo(getMeasuredWidth()/2+55,getMeasuredHeight()/2-50);

        pathLeo.moveTo(getMeasuredWidth()/2,getMeasuredHeight()/2-80);
        pathLeo.lineTo(getMeasuredWidth()/2,getMeasuredHeight()/2-10);


        pathLeo.moveTo(getMeasuredWidth()/2,getMeasuredHeight()/2-50);
        pathLeo.lineTo(getMeasuredWidth()/2-70,getMeasuredHeight()/2);

        pathLeo.moveTo(getMeasuredWidth()/2,getMeasuredHeight()/2-50);
        pathLeo.lineTo(getMeasuredWidth()/2+70,getMeasuredHeight()/2);


        pathLeo.moveTo(getMeasuredWidth()/2-35 ,getMeasuredHeight()/2-10);
        pathLeo.lineTo(getMeasuredWidth()/2+35 ,getMeasuredHeight()/2-10);
        pathLeo.lineTo(getMeasuredWidth()/2,getMeasuredHeight()/2+20);
        pathLeo.lineTo(getMeasuredWidth()/2,getMeasuredHeight()/2+70);
        pathLeo.lineTo( getMeasuredWidth()/2-25,getMeasuredHeight()/2+60);

        pathLeo.moveTo(getMeasuredWidth()/2-50 ,getMeasuredHeight()/2+30);
        pathLeo.lineTo(getMeasuredWidth()/2+50 ,getMeasuredHeight()/2+30);





        pathMeasure = new PathMeasure(pathLeo, true);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isStart) {
            canvas.drawArc(mRectF, 90, 360, false, paint);
            canvas.drawPath(path, oKpaint);
            return;
        }

        canvas.drawArc(mRectF, 90, currentProgress, false, paint);

        if (currentProgress == 360) {
            paint.setStyle(Paint.Style.FILL_AND_STROKE);
        }

        canvas.drawCircle(centerX, centerY, whiteRadius, circlePaint);
        if (whiteRadius==0){
            Log.e("应该走了的啊",scaceRadius+"");
            circlePaint.setColor(getResources().getColor(R.color.pink));
            canvas.drawCircle(centerX, centerY, scaceRadius, circlePaint);
        }

        if (startLine){
            oKpaint.setColor(Color.BLACK);
            canvas.drawPath(pathLeo,oKpaint);
        }


    }

    //dp值转换成px值
    private int dp2px(float dpValue) {
        return DisplayUtil.dp2px(getContext(), dpValue);
    }


    public void start() {
//        animatorSet.play(animator_circle).before(animator_white).before(animator_scace);
        animatorSet.play(animator_white).after(animator_circle).before(animator_scace).before(animator_line);
        animatorSet.start();
    }


    public interface ClickAndAnim {

        void onClickListener();

        void onAnimFish();
    }




}


Main里的代码则是:

public class MainActivity extends AppCompatActivity {
    private TickView tickView;
    private ImageView image;

    private static final int ANIM_TIME = 2000;
    private static final float SCALE_END = 1.2F;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tickView = (TickView) findViewById(R.id.tickView);
        image = (ImageView) findViewById(R.id.image);
        tickView.setListener(new TickView.ClickAndAnim() {
            @Override
            public void onClickListener() {
                tickView.start();
            }

            @Override
            public void onAnimFish() {
                startAnim();
            }
        });

    }


    private void startAnim() {

        ObjectAnimator animatorX = ObjectAnimator.ofFloat(image, "scaleX", 1f, SCALE_END);
        ObjectAnimator animatorY = ObjectAnimator.ofFloat(image, "scaleY", 1f, SCALE_END);

        AnimatorSet set = new AnimatorSet();
        set.setDuration(ANIM_TIME).play(animatorX).with(animatorY);
        set.start();

        set.addListener(new AnimatorListenerAdapter()
        {

            @Override
            public void onAnimationEnd(Animator animation)
            {


            }
        });
    }
}