专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Android 使用TextView实现验证码输入框

一、需求问题

网上开源的是构建同等数量的EditText,这种存在很多缺陷,主要如下

1、数字/字符键盘切换后状态无法保存

2、焦点切换无法判断

3、光标位置无法修正

为了解决上述问题,使用TextView实现输入框,需要解决的问题是

1、允许TextView可编辑输入

2、修改onDraw实现

效果如下

104_1.png

二、使用TextView 实现输入框

public class EditTextView extends TextView implements TextWatcher {

    private final int INPUT_BOX_NUM = 5;

    private int mBoxSpace = 10;

    public EditTextView(Context context) {
        this(context,null);
    }

    public EditTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public EditTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setFocusable(true);
        setFocusableInTouchMode(true); //支持触摸聚焦
        setClickable(true);
        setGravity(Gravity.CENTER_VERTICAL);
        setMaxLines(1);
        setFilters(new InputFilter[]{
                new InputFilter.LengthFilter(INPUT_BOX_NUM)
        });
        if(Build.VERSION.SDK_INT>=23) {
            setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
        }
        mBoxSpace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,context.getResources().getDisplayMetrics());
        addTextChangedListener(this);

    }

    @Override
    protected boolean getDefaultEditable() {
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
       // super.onDraw(canvas);
        TextPaint paint = getPaint();

        int strokeWidth = (int) paint.getStrokeWidth();

        int boxWidth  =  (getWidth()- strokeWidth*2 - (INPUT_BOX_NUM-1)*mBoxSpace)/INPUT_BOX_NUM;
        int boxHeight = getHeight() -  strokeWidth*2;

        RectF rectF = null;

        Paint.Style style = paint.getStyle();
        Paint.Align align = paint.getTextAlign();
        paint.setTextAlign(Paint.Align.CENTER);

        paint.setStyle(Paint.Style.STROKE);
        paint.setTextAlign(Paint.Align.CENTER);
        String text = getText().toString();
        for (int i=0;i<INPUT_BOX_NUM;i++){
            rectF = new RectF(
                    i*(boxWidth+mBoxSpace),
                    0,
                    i*(boxWidth+mBoxSpace)+boxWidth,
                    boxHeight
            );

            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
            float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
            int baseLineY = (int) (rectF.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式

            canvas.drawRoundRect(rectF,0,0,paint);
            if(text.length()>i) {
                String CH = String.valueOf(text.charAt(i));
                canvas.drawText(CH,rectF.centerX(),baseLineY,paint);
            }

        }
        paint.setStyle(style);
        paint.setTextAlign(align);
    }

    /**
     * 控制是否返回完整文本
     * @return
     */
    @Override
    public boolean getFreezesText() {
        return true;
    }

    @Override
    public Editable getText() {
        return (Editable) super.getText();
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, BufferType.EDITABLE);
    }
    /**
     * 控制光标展示
     * @return
     */
    @Override
    protected MovementMethod getDefaultMovementMethod() {
        return ArrowKeyMovementMethod.getInstance();
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {

    }
}

文章永久链接:https://tech.souyunku.com/18958

未经允许不得转载:搜云库技术团队 » Android 使用TextView实现验证码输入框

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们