自定义View系列(四) 计步器效果的实现

如果你留意的话,在QQ和支付宝都有运动步数控件,今天简单实现一个简单的运动步数效果

1.自定义属性

不做过多解释,直接上代码

 
    
    
    
    
    


 public class stepsView extends View {

 //初始化默认值
private int mOuterColor= Color.RED;
private int mInterColor=Color.BLUE;
private int mBorderWidth=20;
private int mStepTextSize=15;
private int mStepTextColor=Color.RED;
private Paint mOutPaint,mIntPaint,mTextPaint;

//最大和当前步数
private int mStepsMax=50000;
private int mCurrentStep=10000;

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

public stepsView(Context context, AttributeSet attrs) {
    this(context, attrs,0);
}

public stepsView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    //1.确定自定义属性
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.stepsView);
    mOuterColor=array.getColor(R.styleable.stepsView_outerColor, mOuterColor);
    mInterColor=array.getColor(R.styleable.stepsView_interColor,mInterColor);
    mStepTextColor=array.getColor(R.styleable.stepsView_stepTextColor, mStepTextColor);
    mBorderWidth=(int)array.getDimension(R.styleable.stepsView_borderWidth,mBorderWidth);
    mStepTextSize=array.getDimensionPixelSize(R.styleable.stepsView_stepTextSize,mStepTextSize);
    array.recycle();

}
2.测量
 @Override
  protected 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);

} 
3.画外圆弧
    //外圆弧 画笔
    mOutPaint=new Paint();
    mOutPaint.setAntiAlias(true);
    mOutPaint.setStrokeWidth(mBorderWidth);
    mOutPaint.setColor(mOuterColor);
    //圆形结束
    mOutPaint.setStrokeCap(Paint.Cap.ROUND);
    mOutPaint.setStyle(Paint.Style.STROKE);//画笔空心

    //中心点
    int center= getWidth()/2;
    //半径
    int radius=getWidth()/2-mBorderWidth/2;
    //矩形
    RectF rectF=new RectF(center-radius,center-radius,center+radius,center+radius);
    canvas.drawArc(rectF,135,270,false,mOutPaint);
3.画内圆弧
  //内圆弧 画笔
    mIntPaint=new Paint();
    mIntPaint.setAntiAlias(true);
    mIntPaint.setStrokeWidth(mBorderWidth);
    mIntPaint.setColor(mInterColor);
    //圆形结束
    mIntPaint.setStrokeCap(Paint.Cap.ROUND);
    mIntPaint.setStyle(Paint.Style.STROKE);//画笔空心


     if (mStepsMax==0)return;
     float sweepAngle= (float)mCurrentStep/mStepsMax;
     canvas.drawArc(rectF,135,sweepAngle*270,false,mIntPaint);
4.绘制文字
   //内圆弧 画笔
    mTextPaint=new Paint();
    mTextPaint.setAntiAlias(true);
    mTextPaint.setColor(mStepTextColor);
    mTextPaint.setTextSize(mStepTextSize);

   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)/2-fontMetricsInt.bottom;
     int baseline=getHeight()/2 +dy;
    canvas.drawText(stepText,dx,baseline,mTextPaint);
5.完善
   public synchronized void setStepMax(int stepMax){
     this.mStepsMax=stepMax;
    }
   public synchronized void setCurrentStep(int currentStep){
    this.mCurrentStep=currentStep;

    //不断绘制
    invalidate();
   }
5.设置属性动画和使用
   stepView = (stepsView) findViewById(R.id.step_view);
    stepView.setStepMax(4000);

    //属性动画
  ValueAnimator valueAnimator= ObjectAnimator.ofFloat(0, 3000);
  valueAnimator.setDuration(1000);
  valueAnimator.setInterpolator(new DecelerateInterpolator());
  valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float currentstep = (float) animation.getAnimatedValue();
            stepView.setCurrentStep((int)currentstep);

        }
    });
    valueAnimator.start();

你可能感兴趣的:(自定义View系列(四) 计步器效果的实现)