效果图:
1、attrs.xml中
<declare-styleable name="QQStepView"><attr name="outerColor" format="color"/><attr name="innerColor" format="color"/><attr name="borderWidth" format="dimension"/><attr name="stepViewTextSize" format="dimension"/><attr name="stepViewTextColor" format="color"/></declare-styleable>
2、QQStepView
public class QQStepView extends View {private int mOuterColor = Color.GRAY;private int mInnerColor = Color.RED;private float mBorderWidth = 20.0f;//20代表的20pxprivate float mStepViewTextSize = 12.0f;private int mStepViewTextColor = Color.BLACK;private Paint mOutPaint;private int mStepMax;//最大的数值private int mCurrentStep;//当前的数值private Paint mInnerPaint;private Paint mTextPaint;public QQStepView(Context context) {this(context, null);}public QQStepView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public QQStepView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//1分析效果//2确定自定义属性,编写attr.xml//3在布局中使用//4在自定义View中获取自定义属性//5onMeasure//6onDrawTypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQStepView);mOuterColor = array.getColor(R.styleable.QQStepView_outerColor, mOuterColor);mInnerColor = array.getColor(R.styleable.QQStepView_innerColor, mInnerColor);mBorderWidth = array.getDimension(R.styleable.QQStepView_borderWidth, mBorderWidth);mStepViewTextColor = array.getColor(R.styleable.QQStepView_stepViewTextColor, mStepViewTextColor);mStepViewTextSize = array.getDimension(R.styleable.QQStepView_stepViewTextSize, mStepViewTextSize);array.recycle();//外层圆弧画笔mOutPaint = new Paint();mOutPaint.setAntiAlias(true);mOutPaint.setStrokeWidth(mBorderWidth);mOutPaint.setColor(mOuterColor);mOutPaint.setStrokeCap(Paint.Cap.ROUND);//两端变圆弧// mOutPaint.setStyle(Paint.Style.FILL); mOutPaint.setStyle(Paint.Style.STROKE);//内层圆弧画笔mInnerPaint = new Paint();mInnerPaint.setAntiAlias(true);mInnerPaint.setStrokeWidth(mBorderWidth);mInnerPaint.setColor(mInnerColor);mInnerPaint.setStrokeCap(Paint.Cap.ROUND);//两端变圆弧// mOutPaint.setStyle(Paint.Style.FILL); mInnerPaint.setStyle(Paint.Style.STROKE);//文字画笔mTextPaint = new Paint();mInnerPaint.setAntiAlias(true);mInnerPaint.setColor(mStepViewTextColor);mTextPaint.setTextSize(mStepViewTextSize);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);//在布局文件中,可能wrap_content,可能高宽不一致//获取模式 AT_MOST//宽度高度不一致时取最小值,保持是个正方形int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(width > height ? height : width, width > height ? height : width);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画外圆弧:// int center = getWidth() / 2;// int radius= (int) (getWidth()/2-mBorderWidth/2);// RectF rectF = new RectF(center-radius, center-radius, center+radius, center+radius);// int radius = (int) (getWidth() / 2 - mBorderWidth / 2);RectF rectF = new RectF(mBorderWidth / 2, mBorderWidth / 2, getWidth() - mBorderWidth / 2,getWidth() - mBorderWidth / 2);canvas.drawArc(rectF, 135, 270, false, mOutPaint);//画内圆弧:百分比,由用户设置的if (mStepMax == 0) {return;//防止第一次进入时为0,引起错误 }float sweepAngle = (float) mCurrentStep / mStepMax;canvas.drawArc(rectF, 135, sweepAngle * 270, false, mInnerPaint);//画文字String stepText = mCurrentStep + "";Rect textBounds = new Rect();mTextPaint.getTextBounds(stepText, 0, stepText.length(), textBounds);int dx = getWidth() / 2 - textBounds.width() / 2;//文字的起始位置//基线Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();int dy = (fontMetricsInt.bottom = fontMetricsInt.top) - fontMetricsInt.bottom;int baseLine = getHeight() / 2 + dy;canvas.drawText(stepText, dx, baseLine, mTextPaint);}//其他,动画效果等public synchronized void setStepMax(int stepMax) {this.mStepMax = stepMax;}// synchronized,防止多线程操作出错public synchronized void setCurrentStep(int currentStep) {this.mCurrentStep = currentStep;//不断绘制 invalidate();}}
3、在Activity布局中
<com.siberiadante.view.QQStepViewandroid:id="@+id/step_view"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"app:borderWidth="10dp"app:innerColor="@color/blue"app:outerColor="@color/colorAccent"app:stepViewTextColor="@color/blue"app:stepViewTextSize="28sp" />
4、在Activity中
mTvStart = (TextView) findViewById(R.id.tv_start);stepView = (QQStepView) findViewById(R.id.step_view);stepView.setStepMax(10000);// stepView.setCurrentStep(5000);//属性动画final ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 9000);valueAnimator.setDuration(3000);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {float value = (float) valueAnimator.getAnimatedValue();stepView.setCurrentStep((int)value);}});mTvStart.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {valueAnimator.start();}});}
我的微信公众号:tstongxiao
github地址:/SiberiaDante/SiberiaDanteLib/blob/master/siberiadante/src/main/java/com/siberiadante/view/QQStepView.java
参考文章:/p/4e0eb9bb09ab