美文网首页
Android 从 0 开始学习自定义 View(二) 自定义圆

Android 从 0 开始学习自定义 View(二) 自定义圆

作者: 是刘航啊 | 来源:发表于2020-12-10 11:33 被阅读0次

    1.自定义 View 的基本流程

    • 创建 View Class
    • 创建 attr 属性文件,确定属性
    • View Class 绑定 attr 属性
    • onMeasure 测量
    • onDraw 绘制
    1.1 创建 View Class
    public class ArcView extends View {
        public ArcView(Context context) {
            this(context, null);
        }
        public ArcView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }
    
    1.2 创建 attr 属性
    <declare-styleable name="ArcView">
        <!--内环颜色-->
        <attr name="arcInnerColor" format="color" />
        <!--外环颜色-->
        <attr name="arcOutColor" format="color" />
        <!--环大小-->
        <attr name="arcWidth" format="dimension" />
        <!--文字-->
        <attr name="arcText" format="string" />
         <!--文字大小-->
        <attr name="arcTextSize" format="dimension" />
        <!--文字颜色-->
        <attr name="arcTextColor" format="color" />
    </declare-styleable>
    
    1.3 绑定属性
    private void initAttr(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
        //外环颜色
        mInnerColor = array.getColor(R.styleable.ArcView_arcInnerColor, mInnerColor);
        //内环颜色
        mOutColor = array.getColor(R.styleable.ArcView_arcOutColor, mOutColor);
        //环大小
        mWidth = (int) array.getDimension(R.styleable.ArcView_arcWidth, mWidth);
        //文字
        mText = array.getString(R.styleable.ArcView_arcText);
        //文字大小
        mTextSize = array.getDimensionPixelSize(R.styleable.ArcView_arcTextSize, mTextSize);
        //文字颜色
        mTextColor = array.getColor(R.styleable.ArcView_arcTextColor, mTextColor);
        array.recycle();
    }
    
    1.4 onMeasure
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //确保正方形,将短边的大小设为狂傲
        //宽
        int width = MeasureSpec.getSize(widthMeasureSpec);
        //高
        int height = MeasureSpec.getSize(heightMeasureSpec);
        //设置宽高
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }
    
    1.5 onDraw
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
    
    • 第一步,画内环
    private void initInnerPaint() {
        mInnerPaint = new Paint();
        //抗锯齿
        mInnerPaint.setAntiAlias(true);
        //防抖动
        mInnerPaint.setDither(true);
        //宽度
        mInnerPaint.setStrokeWidth(mWidth);
        //颜色
        mInnerPaint.setColor(mInnerColor);
        //设置状态
        mInnerPaint.setStyle(Paint.Style.STROKE);
        //头部小圆点
        mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
    }
    
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画内环
        RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
        canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
    }
    
    内环
    • 第二步,画外环
    private void initOutPaint() {
        mOutPaint = new Paint();
        //抗锯齿
        mOutPaint.setAntiAlias(true);
        //防抖动
        mOutPaint.setDither(true);
        //宽度
        mOutPaint.setStrokeWidth(mWidth);
        //颜色
        mOutPaint.setColor(mOutColor);
        //设置状态
        mOutPaint.setStyle(Paint.Style.STROKE);
        //头部小圆点
        mOutPaint.setStrokeCap(Paint.Cap.ROUND);
    }
    
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画内环
        RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
        canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
        //画内环
        if (MaxProgress == 0) return;
        float sweepAngle = (float) CurrentProgress / MaxProgress;
        canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
    }
    
    外环
    • 第三步,画文字
    private void initTextPaint() {
        mTextPaint = new Paint();
        //抗锯齿
        mTextPaint.setAntiAlias(true);
        //文字大小
        mTextPaint.setTextSize(mTextSize);
        //文字颜色
        mTextPaint.setColor(mTextColor);
    }
    
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画内环
        RectF rectF = new RectF(mWidth / 2, mWidth / 2, getWidth() - mWidth / 2, getHeight() - mWidth / 2);
        canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
        //画内环
        if (MaxProgress == 0) return;
        float sweepAngle = (float) CurrentProgress / MaxProgress;
        canvas.drawArc(rectF, 135, sweepAngle * 270, false, mOutPaint);
        //画文字
        //测量文字宽度
        Rect rect = new Rect();
        mTextPaint.getTextBounds(mText, 0, mText.length(), rect);
        int x = getWidth() / 2 - rect.width() / 2;
        //基线
        Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
        int y = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
        int baseline = getHeight() / 2 + y;
        canvas.drawText(mText, x, baseline, mTextPaint);
    }
    
    最终效果图
    自定义圆弧就介绍到这里了,如果有什么写得不对的,可以在下方评论留言,我会第一时间改正。

    Github 源码链接

    相关文章

      网友评论

          本文标题:Android 从 0 开始学习自定义 View(二) 自定义圆

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