自定义view 仿qq步数 半圆弧

先看效果图:

在这里插入图片描述

自定义属性


    <declare-styleable name="QQSteps">
        <attr name="roundWidth" format="dimension" />
        <attr name="roundColor" format="color" />
        <attr name="progressColor" format="color" />
        <attr name="progressStep" format="integer" />
        <attr name="maxStep" format="integer" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>

自定义view 仿qq步数

package com.demo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import com.demo.myapp.R;

/**
 * 仿qq步数 半圆弧
 *
 * @author gestwr
 * @date 2023/2/8
 */
public class QQSteps extends View {
    
    

    private int mRoundWidth;
    private int mRoundColor;
    private int mProgressColor;
    private int mProgressStep;
    private int mMaxStep;
    private int mTextSize;
    private int mTextColor;

    private static final Paint mPaint = new Paint();
    private int mViewWidth;
    private int mViewHeight;
    private int colorPrimary;
    private int colorAccent;
    private float percent;
    private RectF oval;

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

    public QQSteps(Context context, @Nullable AttributeSet attrs) {
    
    
        super(context, attrs);
        initView(context, attrs, 0);
    }

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

    private void initView(Context context, AttributeSet attrs, int defStyleAttr) {
    
    
    	//默认圆弧颜色:底色 强调色
        colorPrimary = 0x33559bff;
        colorAccent = 0xFFFF4081;

        // 获取TypedArray
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.QQSteps);
        mRoundWidth = typedArray.getDimensionPixelSize(R.styleable.QQSteps_roundWidth, 20);
        mRoundColor = typedArray.getColor(R.styleable.QQSteps_roundColor, colorPrimary);
        mProgressColor = typedArray.getColor(R.styleable.QQSteps_progressColor, colorAccent);
        mProgressStep = typedArray.getInt(R.styleable.QQSteps_progressStep, 0);
        mMaxStep = typedArray.getInt(R.styleable.QQSteps_progressStep, 100);
        mTextColor = R.color.colorAAA;
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.QQSteps_progressStep, 40);
        // 回收
        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
    
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mViewWidth = getMeasuredWidth();
        mViewHeight = getMeasuredHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
    
    
        // 1.画背景大圆弧
        int centerX = mViewWidth / 2;
        int centerY = mViewHeight / 2;
        // 设置圆弧画笔的宽度
        mPaint.setStrokeWidth(mRoundWidth);
        // 设置为 ROUND
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        // 设置画笔颜色
        mPaint.setColor(mRoundColor);
        mPaint.setStyle(Paint.Style.STROKE);
        // 半径
        int radius = (int) (centerX - mRoundWidth/2);
        oval = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
        // 画背景圆弧
        canvas.drawArc(oval, 180, 180, false, mPaint);

        // 2.画进度圆弧
        mPaint.setColor(mProgressColor);
        // 计算当前百分比
        percent = (float) mProgressStep / mMaxStep;
        // 根据当前百分比计算圆弧扫描的角度
        canvas.drawArc(oval, 180, percent * 180, false, mPaint);

        // 3.画文字 重置画笔
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
        String mStep = ((int) (percent * mMaxStep)) + "";
        // 测量文字的宽高
        Rect textBounds = new Rect();
        mPaint.getTextBounds(mStep, 0, mStep.length(), textBounds);
        int dx = (getWidth() - textBounds.width()) / 2;
        // 获取画笔的FontMetrics
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        // 计算文字的基线
        int baseLine = (int) (getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
        // 绘制步数文字
        canvas.drawText(mStep, dx, baseLine, mPaint);
    }

    // 设置当前最大步数
    public synchronized void setMaxStep(int maxStep) {
    
    
        if (maxStep < 0) {
    
    
            throw new IllegalArgumentException("maxStep 不能小于0!");
        }
        this.mMaxStep = maxStep;
    }

    public synchronized int getMaxStep() {
    
    
        return mMaxStep;
    }

    // 设置进度
    public synchronized void setProgress(int progress) {
    
    
        if (progress < 0) {
    
    
            throw new IllegalArgumentException("progress 不能小于0!");
        }
        this.mProgressStep = progress;
        // 重新刷新绘制 -> onDraw()
        invalidate();
    }

    public synchronized int getProgress() {
    
    
        return mProgressStep;
    }

    public float getPercent() {
    
    
        return percent;
    }

    public void setRoundWidth(int mRoundWidth) {
    
    
        this.mRoundWidth = mRoundWidth;
    }

    public void setRoundColor(int mRoundColor) {
    
    
        this.mRoundColor = mRoundColor;
    }

    public void setProgressColor(int mProgressColor) {
    
    
        this.mProgressColor = mProgressColor;
    }

    public void setTextSize(int mTextSize) {
    
    
        this.mTextSize = mTextSize;
    }

    public void setTextColor(int mTextColor) {
    
    
        this.mTextColor = mTextColor;
    }

    public void setColorPrimary(int colorPrimary) {
    
    
        this.colorPrimary = colorPrimary;
    }

    public void setColorAccent(int colorAccent) {
    
    
        this.colorAccent = colorAccent;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44256828/article/details/128938650