自定义控件-进度圆环
2021-06-01 本文已影响0人
lostmypieces
1.分解步骤
- 1.分析效果
- 2.确定自定义属性,编写attrs.xml
- 3.在布局中使用
- 4.在自定义view中获取属性
- 5.onMeacher()
- 5.ondraw()画图 画外圆弧 画内圆弧 画文字
- 6.其他处理(动画效果)
2.具体步骤
- attrs.xml文件 定义需要的控件内部属性变量
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="QQsetView">
<attr name="outerColor" format="color"/>
<attr name="innerColor" format="color"/>
<attr name="borderWidth" format="dimension"/>
<attr name="stepTextSize" format="dimension"/>
<attr name="stepTextColor" format="color"/>
</declare-styleable>
</resources>
- 在layout布局中使用
<com.incall.apps.qqsetview.QQsetView
android:id="@+id/step"
app:outerColor="@color/blue"
app:innerColor="@color/red"
app:stepTextSize="50sp"
app:stepTextColor="@color/red"
app:borderWidth="6dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- 编写控件类QQsetView.class
public class QQsetView extends View {
private int mOuterColor = Color.BLUE;//外圆环颜色
private int mInnerColor = Color.RED;//内圆环颜色
private int mBorderWidth = 20;//圆环宽度
private int mStepTextSize = 16;//文字字体大小
private int mStepTextColor = Color.RED;//文字颜色
private Paint mOutPaint, mInnerPaint, mTextPaint;//外圆环,内圆环,文字画笔
private int mCurrentStep = 0;//当前步数
private int mStepMax = 0;//最大(总共)步数
public QQsetView(Context context) {
this(context, null);
}
public QQsetView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public QQsetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public QQsetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
//4.在自定义view中获取属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQsetView);
mOuterColor = array.getColor(R.styleable.QQsetView_outerColor, mOuterColor);
mInnerColor = array.getColor(R.styleable.QQsetView_innerColor, mInnerColor);
mBorderWidth = (int) array.getDimension(R.styleable.QQsetView_borderWidth, mBorderWidth);
mStepTextSize = array.getDimensionPixelSize(R.styleable.QQsetView_stepTextSize, mStepTextSize);
mStepTextColor = array.getColor(R.styleable.QQsetView_stepTextColor, mStepTextColor);
//定义外弧画笔
mOutPaint = new Paint();
mOutPaint.setColor(mOuterColor);
mOutPaint.setAntiAlias(true);
mOutPaint.setStrokeWidth(mBorderWidth);
mOutPaint.setStrokeCap(Paint.Cap.ROUND);
mOutPaint.setStyle(Paint.Style.STROKE);//画笔空心
//定义内弧画笔
mInnerPaint = new Paint();
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setAntiAlias(true);
mInnerPaint.setStrokeWidth(mBorderWidth);
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
mInnerPaint.setStyle(Paint.Style.STROKE);//画笔空心
//定义文字画笔
mTextPaint = new Paint();
mTextPaint.setColor(mStepTextColor);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mStepTextSize);
//回收
array.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//判断设置的何种模式
//获取模式AT_MOST 40dp
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
//高度不一致,取最小值,以确保为正方形
setMeasuredDimension(width > height ? height : width, width > height ? height : width);
}
//5.画图 画外圆弧 画内圆弧 画文字
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//定义圆心 半径
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);
//内弧
float sweepAngle = (float) mCurrentStep / mStepMax;
if (sweepAngle == 0) {
return;
}
canvas.drawArc(rectF, 135, sweepAngle * 270, false, mInnerPaint);
//文字
//dx 文字左侧偏移量
String stepText = mCurrentStep + "";
Rect textBounds = new Rect();
mTextPaint.getTextBounds(stepText, 0, stepText.length(), textBounds);
int dx = getWidth() / 2 - textBounds.width() / 2;
//基线baseline
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);
}
//其他,设置动画
public synchronized void setmCurrentStep(int mCurrentStep) {
this.mCurrentStep = mCurrentStep;
invalidate();
}
public synchronized void setmStepMax(int mStepMax) {
this.mStepMax = mStepMax;
invalidate();
}
}
- MainActivity类
QQsetView qQsetstep = findViewById(R.id.step);
qQsetstep.setmStepMax(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();
qQsetstep.setmCurrentStep((int) currentStep);
}
});
valueAnimator.start();