功能介绍
- 支持更多步
- 全屏适配,支持横屏
- 可精细化步进操作,如下支持小点先行
当然可以更多定制操作,下面给出所有源代码,代码很简单,根据需要修改。
效果图
第一步 | 第二步 | 第三步 |
---|---|---|
支持小点先行
修改i <= step_number
即可
if (i <= step_number) {
dotPaint.setColor(color_ffb93E);
} else {
dotPaint.setColor(color_666666);
}
支持更多步
arrays
<string-array name="change_phonenumber_step_name">
<item>身份验证</item>
<item>设置新手机号</item>
<item>更换成功</item>
</string-array>
xml
<com.xxx.xxx.xxx.view.ChangePhoneNumberStepView
android:layout_width="match_parent"
android:id="@+id/changep_honenumber_stepview"
android:layout_height="100dp"
phonecontrol:step_array_ids="@array/change_phonenumber_step_name"
tools:step_number="0">
ps :修改tools:step_number 可直接预览查看效果
源代码
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.LinearLayout;
/**
* 文件名:ChangePhoneNumberStepView
* 描 述:
* 作 者:maqi
* 时 间:2022/4/11 11:03
*/
public class ChangePhoneNumberStepView extends LinearLayout {
private int step_array_ids;
private int step_number;
private String[] step_array_ids_strings;
private int fatherWidth;
private int fatherHeight;
private RectF fatherRectF;
private Paint dotPaint;
private TextPaint textPaint;
private Context mContext;
private int color_666666;
private int color_999999;
private int color_ffb93E;
private int color_4DFFB93E;
private int textsize;
private int padding;
private int dotmargin;
private int dotboard;
private int dotmaxboard;
private int dotminwidth;
public interface StepListener {
void step(int step_number);
void complete();
}
private StepListener stepListener;
public void setStepListener(StepListener stepListener) {
this.stepListener = stepListener;
}
public ChangePhoneNumberStepView(Context context) {
super(context);
mContext = context;
}
public ChangePhoneNumberStepView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.changephonenumberstepview);
step_array_ids = a.getResourceId(R.styleable.changephonenumberstepview_step_array_ids, R.array.change_phonenumber_step_name);
step_array_ids_strings = context.getResources().getStringArray(step_array_ids);
step_number = a.getInteger(R.styleable.changephonenumberstepview_step_number, 0);
a.recycle();
init();
}
public ChangePhoneNumberStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.changephonenumberstepview);
step_array_ids = a.getResourceId(R.styleable.changephonenumberstepview_step_array_ids, R.array.change_phonenumber_step_name);
step_array_ids_strings = context.getResources().getStringArray(step_array_ids);
step_number = a.getInteger(R.styleable.changephonenumberstepview_step_number, 0);
a.recycle();
init();
}
private void init() {
setWillNotDraw(false);
Log.d("sssss", "step_number " + step_number);
Log.d("sssss", "step_array_ids_strings " + step_array_ids_strings[0]);
textsize = dp2px(mContext, 14);
padding = dp2px(mContext, 40);
dotmargin = dp2px(mContext, 20);
/*大点 边框*/
dotboard = dp2px(mContext, 4);
/*点直径*/
dotmaxboard = dp2px(mContext, 12);
/*小点直径*/
dotminwidth = dp2px(mContext, 8);
initPaint();
}
private void initPaint() {
color_666666 = mContext.getResources().getColor(R.color.color_666666);
color_999999 = mContext.getResources().getColor(R.color.color_999999);
color_ffb93E = mContext.getResources().getColor(R.color.color_FFB93E);
color_4DFFB93E = mContext.getResources().getColor(R.color.color_4DFFB93E);
dotPaint = new Paint();
dotPaint.setStyle(Paint.Style.FILL);
dotPaint = new Paint(color_ffb93E);
textPaint = new TextPaint();
textPaint.setColor(color_999999);
textPaint.setTextSize(textsize);
}
public static int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(1, dpVal, context.getResources().getDisplayMetrics());
}
private float getTextH(TextPaint pFont, String text) {
Rect rect = new Rect();
pFont.getTextBounds(text, 0, text.length(), rect);
return rect.height();
}
private float getTextW(TextPaint pFont, String text) {
return pFont.measureText(text);
}
public int getStep_number() {
return step_number;
}
public void next() {
if (step_number < step_array_ids_strings.length - 1) {
this.step_number++;
if (null != stepListener) {
stepListener.step(step_number);
}
if (step_number == step_array_ids_strings.length - 1)
if (null != stepListener) {
stepListener.complete();
}
} else {
if (null != stepListener) {
stepListener.complete();
}
}
invalidate();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
float width = fatherRectF.width();
float height = fatherRectF.height();
int length = step_array_ids_strings.length;
float delta/*大球间隙*/ = (width - padding * 2/*边距*/ - dotmaxboard - 2 * dotboard) / (length - 1);
int mindotSize = 3;
float deltamin = (delta - padding /*边距*/ - dotminwidth * mindotSize) / mindotSize;
float y = height / 2f - dotmaxboard / 2f;
canvas.save();
canvas.translate(padding + dotmaxboard / 2 + dotboard, 0);
for (int i = 0; i < length; i++) {
if (i <= step_number) {
//外环
dotPaint.setColor(color_4DFFB93E);
canvas.drawCircle(delta * i, y, dotmaxboard / 2f + dotboard, dotPaint);
//内环
dotPaint.setColor(color_ffb93E);
canvas.drawCircle(delta * i, y, dotmaxboard / 2f, dotPaint);
//大环文字
textPaint.setColor(color_ffb93E);
String name = step_array_ids_strings[i];
float textW = getTextW(textPaint, name);
float textH = getTextH(textPaint, name);
canvas.drawText(name, delta * i - textW / 2f, y + textH + padding / 2f, textPaint);
} else {
//外环
dotPaint.setColor(color_999999);
canvas.drawCircle(delta * i, y, dotmaxboard / 2f + dotboard, dotPaint);
//内环
dotPaint.setColor(color_666666);
canvas.drawCircle(delta * i, y, dotmaxboard / 2f, dotPaint);
//大环文字
textPaint.setColor(color_999999);
String name = step_array_ids_strings[i];
float textW = getTextW(textPaint, name);
float textH = getTextH(textPaint, name);
canvas.drawText(name, delta * i - textW / 2f, y + textH + padding / 2f, textPaint);
}
}
for (int i = 0; i < length - 1; i++) {
if (i < step_number) {
dotPaint.setColor(color_ffb93E);
} else {
dotPaint.setColor(color_666666);
}
//环间 小点
for (int j = 1; j <= mindotSize; j++) {
canvas.drawCircle(padding / 2f + delta * i + deltamin * j, y, dotminwidth / 2f, dotPaint);
}
}
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
fatherHeight = heightSize;
}
if (widthMode == MeasureSpec.EXACTLY) {
fatherWidth = widthSize;
}
fatherRectF = new RectF(0, 0, fatherWidth, fatherHeight);
Log.d("ssss", "heightMode " + heightMode);
Log.d("ssss", "widthMode " + widthMode);
Log.d("ssss", "widthSize " + widthSize);
Log.d("ssss", "heightSize " + heightSize);
setMeasuredDimension(widthSize, heightSize);
}
}