Android自定义view之利用drawArc实现动态效果

1,443 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

系列文章目录

Android自定义view之利用drawArc实现动态效果


文章最后会附上源码


前言

前几天看了一位字节Android工程师的一篇博客,他实现的是歌词上下滚动的效果,实现的关键就是定义一个偏移量,然后根据情况去修改这个值,最后触发View的重绘来达到效果。于是今天根据这个思路来写一篇简单的文章。


一、准备

在这之前呢,还是得简单描述一下自定义view中的一些准备工作

1.测量

  @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        useWidth = mWidth;
        if (mWidth > mHeight) {
            useWidth = mHeight;
        }
    }

2.初始化画笔

    private void initPaint() {
        //初始化
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(0x88FF0000);
        mPaint.setStrokeWidth(4);

        //初始化
        mFramePaint = new Paint();
        mFramePaint.setAntiAlias(true);
        mFramePaint.setStyle(Paint.Style.STROKE);
        mFramePaint.setStrokeWidth(0);
    }

3.自定义属性

这个案例因为时间关系就不自定义属性了,更多请参考本人以前的文章:Android自定义view之围棋动画


二、关键方法介绍

drawArc

此方法中共有五个参数

  • oval :指定圆弧的外轮廓矩形区域。
  • startAngle: 圆弧起始角度,单位为度。
  • sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。
  • useCenter:为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。
  • paint: 绘制圆弧的画板属性。

三.实现

1.思路

通过改变sweepAngle(上述方法第三个参数)的值,然后刷新View来达到效果

代码如下:

        mSweep += SWEEP_INC;
        if (mSweep > 360) {
            mSweep -= 360;
        }
        //刷新View
        invalidate();

2.效果图

请添加图片描述

源码

MySampleView.java

public class MySampleView extends View {
    private int mWidth;
    private int mHeight;
    private int useWidth, minwidth;
    private Paint mPaint;
    private Paint mFramePaint;
    private RectF mBigOval;
    private float mStart;
    private float mSweep;

    private static final float SWEEP_INC = 2;

    public MySampleView(Context context) {
        super(context);
    }

    public MySampleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

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

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MySampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    private void init() {
        initPaint();
    }
    private void initPaint() {
        //初始化
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(0x88FF0000);
        mPaint.setStrokeWidth(4);

        //初始化
        mFramePaint = new Paint();
        mFramePaint.setAntiAlias(true);
        mFramePaint.setStyle(Paint.Style.STROKE);
        mFramePaint.setStrokeWidth(0);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        useWidth = mWidth;
        if (mWidth > mHeight) {
            useWidth = mHeight;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        init();
        //定义一个最小标识
        minwidth = useWidth / 10;
        mBigOval = new RectF(minwidth, minwidth, minwidth*9, minwidth*9);
        //绘制背景
        canvas.drawColor(Color.WHITE);
        canvas.drawRect(mBigOval, mFramePaint);
        canvas.drawArc(mBigOval, mStart, mSweep, true, mPaint);


        mSweep += SWEEP_INC;
        if (mSweep > 360) {
            mSweep -= 360;
        }
        //刷新View
        invalidate();
    }
}