Android 自定义圆弧计数器(模仿QQ计步器)
作者:互联网
1.自定义属性
在res的values文件夹中新建一个attrs.xml文件,如下图所示:
在attrs.xml文件中自定义我们需要的view属性,定义内容如下所示:
<declare-styleable name="QQStepView">
<!--外围圆弧的颜色-->
<attr name="outerColor" format="color"/>
<!--内围圆弧的颜色-->
<attr name="interColor" format="color"/>
<!--显示数字的文字大小-->
<attr name="stepTextSize" format="dimension"/>
<!--显示数据的颜色-->
<attr name="stepTextColor" format="color"/>
<!--圆弧的边框-->
<attr name="borderWidth" format="dimension"/>
<!--最大的数值-->
<attr name="maxStep" format="integer"/>
<!--当前的数值-->
<attr name="currentStep" format="integer"/>
</declare-styleable>
2.自定义QQStepView 类继承至View类
stepview代码如下所示:
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.view.View;
import androidx.annotation.Nullable;
public class QQStepView extends View {
private int mOuterColor = Color.BLUE;//默认外圆弧的颜色
private int mInterColor = Color.RED;//默认内圆弧的颜色
private int mTextStepColor = Color.RED;//默认显示数据的颜色
private float mBorderWidth = 21;//默认圆弧的宽度
private int mMaxStepValue = 5000;//默认最大的显示数据
private int mCurrentStepValue = 1000;//默认当前的显示数据
private Paint mOuterPaint;//外圆弧的画笔
private Paint mInterPaint;//内圆弧的画笔
private 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 typedArray = context.obtainStyledAttributes(attrs,R.styleable.QQStepView);//从attrs.xml文件中获取自定义属性
mOuterColor = typedArray.getColor(R.styleable.QQStepView_outerColor,mOuterColor);//获取外圆弧的颜色
mInterColor = typedArray.getColor(R.styleable.QQStepView_interColor,mInterColor);//获取内圆弧的颜色
mTextStepColor = typedArray.getColor(R.styleable.QQStepView_stepTextColor,mTextStepColor);//获取显示数据字体的颜色
mBorderWidth = typedArray.getDimension(R.styleable.QQStepView_borderWidth,mBorderWidth);//获取圆弧的宽度
mMaxStepValue = typedArray.getInteger(R.styleable.QQStepView_maxStep,mMaxStepValue);//获取最大的显示数据
mCurrentStepValue = typedArray.getInteger(R.styleable.QQStepView_currentStep,mCurrentStepValue);//获取当前的显示数据
typedArray.recycle();//资源文件的回收
/**定义外圆弧的画笔样式*/
mOuterPaint = new Paint();
mOuterPaint.setAntiAlias(true);
mOuterPaint.setColor(mOuterColor);
mOuterPaint.setStrokeWidth(mBorderWidth);
mOuterPaint.setStrokeCap(Paint.Cap.ROUND);
mOuterPaint.setStyle(Paint.Style.STROKE);
/**定义内圆弧的画笔样式*/
mInterPaint = new Paint();
mInterPaint.setAntiAlias(true);
mInterPaint.setColor(mInterColor);
mInterPaint.setStrokeWidth(mBorderWidth);
mInterPaint.setStrokeCap(Paint.Cap.ROUND);
mInterPaint.setStyle(Paint.Style.STROKE);
/**定义显示字体的画笔样式*/
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(mTextStepColor);
mTextPaint.setTextSize(60);
}
@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 radis = (int) (center - mBorderWidth/2);
//外侧的圆弧
RectF outRect = new RectF(center-radis,center-radis,center+radis,center+radis);
canvas.drawArc(outRect,135,270,false,mOuterPaint);
//内侧的圆弧
float sweepAngle = 0;
if(mCurrentStepValue>0)
sweepAngle= (float) mCurrentStepValue/(float)mMaxStepValue*270;
canvas.drawArc(outRect,135,sweepAngle,false,mInterPaint);
//绘画文字
Rect textRect = new Rect();
mTextPaint.getTextBounds(mCurrentStepValue+"",0,String.valueOf(mCurrentStepValue).length(),textRect);
int dx = getWidth()/2 - textRect.width()/2;
int dy = (textRect.bottom-textRect.top)/2 - textRect.top;
int baseLine = (int) (getHeight()/2 +dy-mBorderWidth);
canvas.drawText(mCurrentStepValue+"",dx,baseLine,mTextPaint);
}
public void setmMaxStepValue(int maxStepValue){
this.mMaxStepValue = maxStepValue;
}
public void setmCurrentStepValue(int currentStepValue){
this.mCurrentStepValue = currentStepValue;
invalidate();
}
}
3.在布局文件中的使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.hong.myview.QQStepView
android:id="@+id/qq_step_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
4.代码中的使用
import androidx.appcompat.app.AppCompatActivity;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.view.animation.DecelerateInterpolator;
public class MainActivity extends AppCompatActivity {
private QQStepView qqStepView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
qqStepView = this.findViewById(R.id.qq_step_view);
qqStepView.setmMaxStepValue(3000);
//添加动画
ValueAnimator valueAnimator = ValueAnimator.ofInt(0,2500);//0-2500数字
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(1500);//1.5s的动画效果
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentStep = (int) animation.getAnimatedValue();//获取当前的动画值,即(0-2500的数字)
qqStepView.setmCurrentStepValue(currentStep);//重新绘制view
}
});
valueAnimator.start();//开启动画
}
}
5.运行结果
标签:QQ,QQStepView,自定义,int,圆弧,Paint,import,计步器,android 来源: https://blog.csdn.net/h5630/article/details/113867269