自定义View之三-画笔(计步器效果)
2017-11-13 本文已影响0人
woochen123
效果图
step.gif1.自定义属性
<declare-styleable name="StepView">
<attr name="maxStep" format="integer"></attr>
<attr name="currentStep" format="integer"/>
<attr name="stepColor" format="color|reference"/>
<attr name="outColor" format="color|reference"/>
<attr name="innerColor" format="color|reference"/>
<attr name="stepSize" format="dimension"/>
<attr name="roundWidth" format="float"/>
</declare-styleable>
2.继承VIew
/**
*@author woochen123
*@time 2017/11/13 15:39
*@desc
*/
public class StepView extends View {
private static final String TAG = "StepView";
//最大步数 默认1000
private int mMaxStep = 100;
//当前步数 默认500
private int mCurrentStep = 50;
//控件宽度
private int mViewWidth;
//空间高度
private int mViewHeight;
//圆环宽度
private int mRoundWidth = 30;
//起始角度
private float mStartAngle = 135;
//旋转角度
private float mSweepAngle = 270;
//步数文字大小 sp
private int mTextSize = 15;
//步数文字颜色
private int mTextColor = Color.RED;
//外层圆环颜色
private int mOutColor = Color.BLUE;
//内层圆环颜色
private int mInnerColor = Color.RED;
public StepView(Context context) {
this(context, null);
}
public StepView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public StepView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StepView);
mMaxStep = array.getInt(R.styleable.StepView_maxStep, mMaxStep);
mRoundWidth = (int) array.getFloat(R.styleable.StepView_roundWidth, mRoundWidth);
mCurrentStep = array.getInt(R.styleable.StepView_currentStep, mCurrentStep);
mTextColor = array.getColor(R.styleable.StepView_stepColor, mTextColor);
mOutColor = array.getColor(R.styleable.StepView_outColor, mOutColor);
mInnerColor = array.getColor(R.styleable.StepView_innerColor, mInnerColor);
mTextSize = array.getDimensionPixelSize(R.styleable.StepView_stepSize, sp2Px(mTextSize));
array.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST) {
//如果是包裹内容
mViewHeight = mViewWidth;
}
setMeasuredDimension(mViewWidth, mViewHeight);
}
@Override
protected void onDraw(Canvas canvas) {
//1.画背景圆弧
int centerX = mViewWidth / 2;
int centerY = mViewHeight / 2;
//半径
int radius = centerX - mRoundWidth;
//矩形区域
RectF oval = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
Paint mPaint = new Paint();
mPaint.setColor(mOutColor);
//设置圆弧的宽度(设置空心线宽)
mPaint.setStrokeWidth(mRoundWidth);
//设置画笔的样式
mPaint.setStyle(Paint.Style.STROKE);
//当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式 Cap.ROUND,或方形样式Cap.SQUARE
mPaint.setStrokeCap(Paint.Cap.ROUND);
//设置结合处的形状,有三个选择:BEVEL、MITER、ROUND,分别表示直线、直角、圆角
mPaint.setStrokeJoin(Paint.Join.ROUND);
//抗锯齿
mPaint.setAntiAlias(true);
//oval:圆弧所在的椭圆对象 startAngle:开始角度 水平向右是0°sweepAngle:旋转角度 useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示 panint:画笔
canvas.drawArc(oval, mStartAngle, mSweepAngle, false, mPaint);
//2.画进度圆弧
mPaint.setColor(mInnerColor);
float currentPercent = mCurrentStep * 1.0f / mMaxStep;
canvas.drawArc(oval, mStartAngle, mSweepAngle * currentPercent, false, mPaint);
//3.画步数文字
//绘制文字
String mStep = mCurrentStep + "";
//重置画笔
mPaint.reset();
//无锯齿
mPaint.setAntiAlias(true);
//设置文字大小
mPaint.setTextSize(mTextSize);
//设置文字颜色
mPaint.setColor(mTextColor);
Log.e(TAG, "onDraw: "+mTextColor );
//测量文字的宽高
Rect textBounds = new Rect();
mPaint.getTextBounds(mStep, 0, mStep.length(), textBounds);
//计算文字的基线
int dx = (getWidth() - textBounds.width()) / 2;
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float baseLine = getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
//text:要绘制的内容 x:基线的横坐标 y:基线的纵坐标 paint:画笔
canvas.drawText(mStep, dx, baseLine, mPaint);
}
private int sp2Px(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sp, getResources().getDisplayMetrics());
}
/**
* 设置最大步数
* @param maxStep
*/
public void setMaxStep(int maxStep) {
if(maxStep < 0 ){
throw new IllegalArgumentException("max 不能小于0!");
}
this.mMaxStep = maxStep;
}
/**
* 设置当前步数
* @param currentStep
*/
public void setCurrentStep(int currentStep) {
if(currentStep < 0 ){
throw new IllegalArgumentException("max 不能小于0!");
}
this.mCurrentStep = currentStep;
invalidate();
}
}
3.使用
<com.example.admin.testapplication.views.step.StepView
android:id="@+id/stepView"
app:stepSize="50sp"
app:stepColor="#00ff00"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
final StepView stepView = (StepView) findViewById(R.id.stepView);
stepView.setMaxStep(1000);
ValueAnimator valueAnimator =ValueAnimator.ofInt(0,800);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
stepView.setCurrentStep(value);
}
});
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.setDuration(1500);
valueAnimator.start();