效果圖是一切代碼的結果
标題
代碼分析:
public XTestStepView(Context context) {
super(context);
init();
}
public XTestStepView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public XTestStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.XQQStepView);
mOuterColor = typedArray.getColor(R.styleable.XQQStepView_outerColor, mOuterColor);
mInnerColor = typedArray.getColor(R.styleable.XQQStepView_innerColor, mInnerColor);
mBorderWidth = (int) typedArray.getDimension(R.styleable.XQQStepView_borderWidth, mBorderWidth);
mStepTextSize = typedArray.getDimensionPixelOffset(R.styleable.XQQStepView_stepTextSize, mStepTextSize);
mStepTextColor = typedArray.getColor(R.styleable.XQQStepView_stepTextColor, mStepTextColor);
typedArray.recycle();
init();
}
自定義控件必要繼承的幾個方法就不多說了,其中第三個方法裡面是設定相關屬性;
定義畫筆工具
private void init() {
//内弧
mOuterPaint = new Paint();
mOuterPaint.setAntiAlias(true);
mOuterPaint.setStrokeWidth(mBorderWidth);
mOuterPaint.setColor(mOuterColor);
mOuterPaint.setStrokeCap(Paint.Cap.ROUND);//設定下方為圓形
mOuterPaint.setStyle(Paint.Style.STROKE);//設定内部為空心
//外弧
mInnerPaint = new Paint();
mInnerPaint.setAntiAlias(true);
mInnerPaint.setStrokeWidth(mBorderWidth);
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);//設定下方為圓形
mInnerPaint.setStyle(Paint.Style.STROKE);//設定内部為空心
//文字
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mStepTextSize);
mTextPaint.setStrokeWidth(2);
mTextPaint.setColor(mStepTextColor);
}
不明白屬性的百度,最基礎的畫筆屬性,沒法再做解釋
接下來擷取寬高:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width > height ? height : width, width > height ? height : width);
}
畫布,解釋在代碼裡面:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫外圓
int center = getWidth() / 2;
int radius = getWidth() / 2 - mBorderWidth / 2;
//mBorderWidth/2,mBorderWidth/2,getWidth()-mBorderWidth/2,getWidth()-mBorderWidth/2
@SuppressLint("DrawAllocation") RectF recf = new RectF(center - radius,
center - radius,
center + radius,
center + radius);
canvas.drawArc(recf, 90, 360, false, mOuterPaint);
//2.繪制内圓弧
float sweepAngle = (float) mCurrentStep / mStepMax;
canvas.drawArc(recf, 90, sweepAngle * 360, false, mInnerPaint);
//3.繪制文字
String stepText = mCurrentStep + "";
Rect rect = new Rect();
mTextPaint.getTextBounds(stepText,0,stepText.length(),rect);
int dx = getWidth() / 2 - rect.width() / 2;
//第一種方式擷取高度
//int dy = getWidth() / 2 + rect.width()/2;
//第二種表達方式擷取高度
Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
//擷取中心(fontMetrics.bottom - fontMetrics.top) / 2
int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
int baseLine = getHeight() / 2 + dy;
canvas.drawText(stepText, dx, baseLine, mTextPaint);
Log.e("stepText:",stepText +"..."+sweepAngle);
}
最後是完整的代碼:
public class XTestStepView extends View {
// <!--内部圓環顔色,外部圓環顔色,圓環寬度,文字顔色,文字大小-->
private int mOuterColor = Color.RED;
private int mInnerColor = Color.BLUE;
private int mBorderWidth = 20;
private int mStepTextSize = 50;
private int mStepTextColor = Color.RED;
private Paint mOuterPaint, mInnerPaint, mTextPaint;
private int mStepMax;//總的步數
private int mCurrentStep;//目前步數
public XTestStepView(Context context) {
super(context);
init();
}
public XTestStepView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public XTestStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.XQQStepView);
mOuterColor = typedArray.getColor(R.styleable.XQQStepView_outerColor, mOuterColor);
mInnerColor = typedArray.getColor(R.styleable.XQQStepView_innerColor, mInnerColor);
mBorderWidth = (int) typedArray.getDimension(R.styleable.XQQStepView_borderWidth, mBorderWidth);
mStepTextSize = typedArray.getDimensionPixelOffset(R.styleable.XQQStepView_stepTextSize, mStepTextSize);
mStepTextColor = typedArray.getColor(R.styleable.XQQStepView_stepTextColor, mStepTextColor);
typedArray.recycle();
init();
}
public XTestStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private void init() {
//内弧
mOuterPaint = new Paint();
mOuterPaint.setAntiAlias(true);
mOuterPaint.setStrokeWidth(mBorderWidth);
mOuterPaint.setColor(mOuterColor);
mOuterPaint.setStrokeCap(Paint.Cap.ROUND);//設定下方為圓形
mOuterPaint.setStyle(Paint.Style.STROKE);//設定内部為空心
//外弧
mInnerPaint = new Paint();
mInnerPaint.setAntiAlias(true);
mInnerPaint.setStrokeWidth(mBorderWidth);
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);//設定下方為圓形
mInnerPaint.setStyle(Paint.Style.STROKE);//設定内部為空心
//文字
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mStepTextSize);
mTextPaint.setStrokeWidth(2);
mTextPaint.setColor(mStepTextColor);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width > height ? height : width, width > height ? height : width);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫外圓
int center = getWidth() / 2;
int radius = getWidth() / 2 - mBorderWidth / 2;
//mBorderWidth/2,mBorderWidth/2,getWidth()-mBorderWidth/2,getWidth()-mBorderWidth/2
@SuppressLint("DrawAllocation") RectF recf = new RectF(center - radius,
center - radius,
center + radius,
center + radius);
canvas.drawArc(recf, 90, 360, false, mOuterPaint);
//2.繪制内圓弧
float sweepAngle = (float) mCurrentStep / mStepMax;
canvas.drawArc(recf, 90, sweepAngle * 360, false, mInnerPaint);
//3.繪制文字
String stepText = mCurrentStep + "";
Rect rect = new Rect();
mTextPaint.getTextBounds(stepText,0,stepText.length(),rect);
int dx = getWidth() / 2 - rect.width() / 2;
//第一種方式擷取高度
//int dy = getWidth() / 2 + rect.width()/2;
//第二種表達方式擷取高度
Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
//擷取中心(fontMetrics.bottom - fontMetrics.top) / 2
int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
int baseLine = getHeight() / 2 + dy;
canvas.drawText(stepText, dx, baseLine, mTextPaint);
Log.e("stepText:",stepText +"..."+sweepAngle);
}
//其他,寫幾個方法讓他動起來
public void setStepMax(int mStepMax) {
this.mStepMax = mStepMax;
}
public void setCurrentStep(int mCurrentStep) {
this.mCurrentStep = mCurrentStep;
//不斷繪制 onDraw()
invalidate();
}
}
接下來,我會将中間的文字放在進度條中,跟随實時