2.自定义view-QQ运动步数


1.效果

2.实现

2.1自定义属性

在res/values 文件夹中新建xx.xml,内容如下

<?xml version="1.0" encoding="utf-8"?>

    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

2.2继承view实现java代码

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

import androidx.annotation.Nullable;

/**
 * Created by DongKing on 2020/11/6
 * Version 1.0
 * Describe:qq步数
 */
class QQStepView extends View {
    private int mStepMax = 10000;//默认最大值
    private int mCurrentStep = 0;//当前值
    private int mOuterColor = Color.RED;
    private int mInnerColor = Color.BLUE;
    private int mOuterWidth = 30;
    private int mInnerWidth = 18;
    private int mStepTextSize = 18;
    private int mStepTextColor = Color.LTGRAY;

    Paint mInnerPaint;//画内圆的画笔
    Paint mOuterPaint;//画外圆的画笔
    Paint mTextPaint;//画文字的画笔


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

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

    public QQStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQStepView);
        mOuterColor = array.getColor(R.styleable.QQStepView_outerColor, mOuterColor);
        mInnerColor = array.getColor(R.styleable.QQStepView_innerColor, mInnerColor);
        mOuterWidth = (int) array.getDimension(R.styleable.QQStepView_outerWidth, mOuterWidth);
        mInnerWidth = (int) array.getDimension(R.styleable.QQStepView_innerWidth, mInnerWidth);
        mStepTextSize = array.getDimensionPixelSize(R.styleable.QQStepView_stepTextSize, mStepTextSize);
        mStepTextColor = array.getColor(R.styleable.QQStepView_stepTextColor, mStepTextColor);
        mStepMax = array.getInt(R.styleable.QQStepView_stepMax, mStepMax);

        array.recycle();
        //初始化画笔
        mOuterPaint = new Paint();
        mOuterPaint.setAntiAlias(true);
        mOuterPaint.setStrokeCap(Paint.Cap.ROUND);
        mOuterPaint.setColor(mOuterColor);
        mOuterPaint.setStrokeWidth(mOuterWidth);
        mOuterPaint.setStyle(Paint.Style.STROKE);
        mInnerPaint = new Paint();
        mInnerPaint.setAntiAlias(true);
        mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
        mInnerPaint.setColor(mInnerColor);
        mInnerPaint.setStrokeWidth(mInnerWidth);
        mInnerPaint.setStyle(Paint.Style.STROKE);
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(mStepTextSize);
        mTextPaint.setColor(mStepTextColor);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //保证是一个正方形
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width > height ? height : width, width > height ? height : width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int center = getWidth() / 2;
        //减去比较大的那个的一半 -->防止超出边界
        int radius = center - (mOuterWidth > mInnerWidth ? mOuterWidth : mInnerWidth) / 2;
        RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);
        //1.画里面的圆弧
        canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
        //2.画外面的圆弧
        if (mStepMax == 0) {
            return;
        }

        float sweepAngle = (float) mCurrentStep / mStepMax * 270;
        canvas.drawArc(rectF, 135, sweepAngle, false, mOuterPaint);
        //3.画文字
        Rect rect = new Rect();
        String stepText = mCurrentStep + "";
        mTextPaint.getTextBounds(stepText, 0, stepText.length(), rect);
        int dx = getWidth() / 2 - rect.width() / 2;

        Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
        int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
        int baseLine = getHeight() / 2 + dy;

        canvas.drawText(stepText, dx, baseLine, mTextPaint);
    }

    public synchronized void setCurrentStep(int currentStep) {
        this.mCurrentStep = currentStep;
        invalidate();
    }
}

3.使用

3.1 布局文件中


        
 

3.2 activity中

public class MainActivity extends AppCompatActivity {
    QQStepView mQqStepView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mQqStepView = findViewById(R.id.qq_step_view);
        init();

    }

    private void init() {
        ValueAnimator valueAnimator = ObjectAnimator.ofInt(0, 8000);
        valueAnimator.setDuration(3000);
        valueAnimator.setInterpolator(new DecelerateInterpolator());
        valueAnimator.addUpdateListener(animation -> {
            int currentStep = (int) animation.getAnimatedValue();
            mQqStepView.setCurrentStep(currentStep);
        });
        valueAnimator.start();
    }

}