如果你留意的话,在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();