Android修行手册 - 自定义验证码输入框

举报
芝麻粒儿 发表于 2022/03/25 22:38:28 2022/03/25
【摘要】 本文约8.2千字,新手阅读需要9分钟,复习需要4分钟 【收藏随时查阅不再迷路】 👉关于作者 众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对...

本文约8.2千字,新手阅读需要9分钟,复习需要4分钟收藏随时查阅不再迷路

👉关于作者

众所周知,人生是一个漫长的流程,不断克服困难,不断反思前进的过程。在这个过程中会产生很多对于人生的质疑和思考,于是我决定将自己的思考,经验和故事全部分享出来,以此寻找共鸣 !!!
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎私我,交流群让学习不再孤单

在这里插入图片描述

👉前提

这是小空坚持写的Android新手向系列,欢迎品尝。

大佬(×)

新手(√)

👉实践过程

😜思路和知识点

前面我们学完了EditText和TextView两个组件,但是,光学不练没意思。
image.png

所以今天我们趁热打铁,利用两个组件实现个自定义验证码输入框。

自定义验证码输入框.gif

思路前瞻:

  1. 隐形EditText接收输入,显性TextView展示内容
  2. 时刻监听EditText回调更改内容
  3. 自定义RelativeLayout

布局代码:

<?xml version="1.0" encoding="utf-8"?><!--自定义验证码View-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F84F64"
    android:paddingTop="100dp">
    <!--线性布局-orientation="horizontal"水平方向-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/txtCode1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/edittext_kuang"
            android:gravity="center"
            android:textColor="#ffffff"
            android:textSize="26sp" />

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />
 
        <TextView
            android:id="@+id/txtCode2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/edittext_kuang"
            android:gravity="center"
            android:textColor="#ffffff"
            android:textSize="26sp" />
 
        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/txtCode3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/edittext_kuang"
            android:gravity="center"
            android:textColor="#ffffff"
            android:textSize="26sp" />

        <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />

        <TextView
            android:id="@+id/txtCode4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/edittext_kuang"
            android:gravity="center"
            android:textColor="#ffffff"
            android:textSize="26sp" />

         <View
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_weight="1" />
    </LinearLayout>

    <EditText
        android:id="@+id/editCode"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/transparent"
        android:inputType="number" />
</RelativeLayout>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

自定义View代码

/**
 * Created by akitaka on 2022-01-26.
 *
 * @author akitaka
 * @filename VerificationCodeViewJava
 * @describe 自定义验证码view-Java代码
 * @email 960576866@qq.com
 */
public class VerificationCodeViewJava extends RelativeLayout {
    private EditText editText;
    private List<TextView> textViewList = new ArrayList<>();
    private StringBuffer stringBuffer = new StringBuffer();

    public VerificationCodeViewJava(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerificationCodeViewJava(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //添加布局内容
        View.inflate(context, R.layout.view_verification_code, this);
        editText = findViewById(R.id.editCode);
        textViewList.add(findViewById(R.id.txtCode1));
        textViewList.add(findViewById(R.id.txtCode2));
        textViewList.add(findViewById(R.id.txtCode3));
        textViewList.add(findViewById(R.id.txtCode4));

        editText.addTextChangedListener(new TextWatcher() {

            @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) {
                //如果有字符输入时才进行操作
                if (!s.toString().equals("")) {
                    //我们限制了4个验证码
                    if (stringBuffer.length() > 3) {
                        editText.setText("");
                        return;
                    } else {
                        stringBuffer.append(s);
                        //因为editText是辅助的,根本字符串是stringBuffer,所以将EditText置空
                        editText.setText("");
                        //现在很多App都是输入完毕后自动进入下一步逻辑,所以咱们一般都是在这监听,完成后进行回调业务即可
                        if (stringBuffer.length() == 4) {
                            //验证码输入完毕了,自动进行验证逻辑
                        }
                    }

                    for (int i = 0; i < stringBuffer.length(); i++) {
                        textViewList.get(i).setText(stringBuffer.charAt(i) + "");
                    }
                }
            }
        });

        //设置删除按键的监听
        editText.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (stringBuffer.length() > 0) {
                        //删除字符
                        stringBuffer.delete(stringBuffer.length() - 1, stringBuffer.length());
                        //将TextView显示内容置空
                        textViewList.get(stringBuffer.length()).setText("");
                    }
                    return true;
                }
                return false;
            }
        });
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
/**
 * Created by akitaka on 2022-01-26.
 * @author akitaka
 * @filename VerificationCodeViewKotlin
 * @describe 自定义验证码view-Kotlin代码
 * @email 960576866@qq.com
 */
class VerificationCodeViewKotlin : RelativeLayout {
    private var editText: EditText? = null
    private val textViewList: MutableList<TextView> = ArrayList()
    private val stringBuffer = StringBuffer()

    constructor(context: Context?) : this(context, null)
    constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    init {
        //添加布局内容
        View.inflate(context, R.layout.view_verification_code, this)
        editText = findViewById(R.id.editCode)
        textViewList.add(findViewById(R.id.txtCode1))
        textViewList.add(findViewById(R.id.txtCode2))
        textViewList.add(findViewById(R.id.txtCode3))
        textViewList.add(findViewById(R.id.txtCode4))

        editText!!.addTextChangedListener(object : TextWatcher {

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
            
            override fun afterTextChanged(s: Editable) {
                //如果有字符输入时才进行操作
                if (s.toString() != "") {
                    //我们限制了4个验证码
                    if (stringBuffer.length > 3) {
                        editText!!.setText("")
                        return
                    } else {
                        stringBuffer.append(s)
                        //因为editText是辅助的,根本字符串是stringBuffer,所以将EditText置空
                        editText!!.setText("")
                        //现在很多App都是输入完毕后自动进入下一步逻辑,所以咱们一般都是在这监听,完成后进行回调业务即可
                        if (stringBuffer.length == 4) {
                            //验证码输入完毕了,自动进行验证逻辑
                        }
                    }
                    for (i in 0 until stringBuffer.length) {
                        textViewList[i].text = stringBuffer[i].toString() + ""
                    }
                }
            }
        })

        //设置删除按键的监听
        editText!!.setOnKeyListener(OnKeyListener { v, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_DEL && event.action == KeyEvent.ACTION_DOWN) {
                if (stringBuffer.length > 0) {
                    //删除字符
                    stringBuffer.delete(stringBuffer.length - 1, stringBuffer.length)
                    //将TextView显示内容置空
                    textViewList[stringBuffer.length].text = ""
                }
                return@OnKeyListener true
            }
            false
        })
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

直接在目标Activity(页面)布局中使用即可

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <cn.appstudy.customView.VerificationCodeViewJava
        android:layout_width="match_parent"
        android:visibility="gone"
        android:layout_height="match_parent" />

    <!-- 或者-->
    <cn.appstudy.customView.VerificationCodeViewKotlin
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

image.png

😜总结

刚学Android的朋友可能又疑惑了,里面涉及了RelativeLayout和自定义View的知识。没错,小空几种验证码的实现方案特意选的这个,这样我们就引出了下一篇文章布局容器的知识:RelativeLayout(相对布局容器)和LinearLayout(线性布局容器)

当然了,设计千奇百怪。上面只是普通的实现,还做过下面俩功能需求

自定义验证码输入,自定义输入键盘的-不推荐

直接包含了输入按键写到整个页面UI里,禁止软(小)键盘弹出的-较推荐

但不管什么需求,用的是EditText或TextView

都逃脱不了EditText的【addTextChangedListener】、【InputFilter】、【android:inputType】几个知识点以及TextView的基本属性应用。

更多需求的创意解决方案就靠大家多想想了,有时候基本的技术解决困难的需求反而更轻松快捷。

👉其他

📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。

温馨提示点击下方卡片获取更多意想不到的资源。
空名先生

文章来源: zhima.blog.csdn.net,作者:芝麻粒儿,版权归原作者所有,如需转载,请联系作者。

原文链接:zhima.blog.csdn.net/article/details/123738759

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。