Android--搜索加载动画

2020-07-03 11:16:34 浏览数 (1)

核心思路:利用PathMeasure,不断截取片段来画到canvas上
代码语言:javascript复制
/**
 * 搜索动画效果2
 */
public class SearchAnimView2 extends View {
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    //搜索图标的圆的半径
    private float searchCircleRadius;
    //搜索图标的线的长度
    private float searchLineWidth;
    //动画效果圆的半径
    private float animeRadius;
    //中心
    private float centerY;
    private float centerX;

    //搜索图标消失动画
    private final int status_dismiss_search = 1;
    //加载动画
    private final int status_progress = 2;
    private int status = status_dismiss_search;

    private float ratio;
    private float ratio2;
    //显示的长度
    private float showLineWidth;

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

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

    public SearchAnimView2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private void init() {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(4);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        int size = getWidth() > getHeight() ? getHeight() : getWidth();

        centerX = centerY = size / 2f;

        searchCircleRadius = size / 6f;
        searchLineWidth = size / 4f;

        animeRadius = size / 2.2f;

        showLineWidth = animeRadius / 3f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //画搜索图标
        if (status == status_dismiss_search) {
            //画搜索圆
            RectF oval = new RectF(centerX - searchCircleRadius, centerY - searchCircleRadius,
                    centerX   searchCircleRadius, centerY   searchCircleRadius);
            if (ratio < 0.5f)
                canvas.drawArc(oval, 45, 360 * ((0.5f - ratio) * 2f), false, mPaint);

            //画线
            canvas.save();
            canvas.rotate(45, centerX, centerY);

            if (ratio > 0.5f && ratio < 1f) {
                canvas.drawLine(centerX   searchCircleRadius, centerY,
                        centerX   searchCircleRadius   searchLineWidth * ((1f - ratio) * 2), centerY, mPaint);
            } else {
                canvas.drawLine(centerX   searchCircleRadius, centerY,
                        centerX   searchCircleRadius   searchLineWidth, centerY, mPaint);
            }

            canvas.restore();
        }

        //画进度
        if (status == status_progress) {
            Path path = new Path();

            RectF oval = new RectF(centerX - animeRadius, centerY - animeRadius,
                    centerX   animeRadius, centerY   animeRadius);
            path.addArc(oval, 45, 359);

            PathMeasure pathMeasure = new PathMeasure(path, false);
            Path path2 = new Path();
            pathMeasure.getSegment(pathMeasure.getLength() * ratio2,
                    pathMeasure.getLength() * ratio2   showLineWidth, path2, true);

            canvas.drawPath(path2, mPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            startAnime();
            return true;
        }
        return super.onTouchEvent(event);
    }

    ValueAnimator valueAnimator;
    ValueAnimator valueAnimator2;

    private void startAnime() {
        valueAnimator = ValueAnimator.ofFloat(1f);
        valueAnimator.setDuration(1000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                status = status_dismiss_search;
                ratio = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                status = status_progress;
                valueAnimator2.start();
            }
        });

        valueAnimator2 = ValueAnimator.ofFloat(1f);
        valueAnimator2.setDuration(2000);
        valueAnimator2.setInterpolator(new LinearInterpolator());
        valueAnimator2.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator2.setRepeatMode(ValueAnimator.REVERSE);
        valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ratio2 = (float) animation.getAnimatedValue();

                postInvalidate();
            }
        });

        valueAnimator.start();
    }
}
项目地址:https://gitee.com/aruba/CanvasApplication.git

0 人点赞