StepView自定义控件功能实现

功能介绍
  1. 支持更多步
  2. 全屏适配,支持横屏
  3. 可精细化步进操作,如下支持小点先行

当然可以更多定制操作,下面给出所有源代码,代码很简单,根据需要修改。

效果图
第一步第二步第三步
第一步第二步第三步
支持小点先行

小点先行
修改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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值