美文网首页
输入框验证

输入框验证

作者: 爱吃豆腐面 | 来源:发表于2016-11-21 16:13 被阅读88次

问题描述

最近做需求时,遇到过几次需要写一个页面,页面上要求用户输入诸如手机号、身份证号、银行卡号这类信息,还有一个提交按钮,每个输入框有特定的输入规则。
初始状态下,输入框里没有内容,提交按钮不能点击;当所有输入框里有输入了内容且满足输入规则时,按钮自动变为可点击状态。

输入规则

手机号规则

  1. 手机号输入必须是11位
  2. 采用3-3-4的输入样式,中间自动加入空格(133 6666 6666)
  3. 输入必须全为数字

身份证号规则

  1. 身份证号输入15位或者18位
  2. 采用6-4-4-4的输入样式(420923 1992 0202 2222)
  3. 输入必须全为数字

银行卡号规则

  1. 银行卡号输入位数必须在8到20位之间,包括8和20
  2. 采用4位一隔的输入样式(6226 2205 0598 6666)
  3. 输入必须全为数字

思路分析

作为码农,很容易为做需求而做需求,在每个地方写上了大量相同的代码逻辑判断,虽然程序运行上没有问题,也完全符合需求,但是如果你真的这样做,那你就真的是个码农啦!因为简单的复制粘贴是最低级的,也是最易错和难改的,在后期的维护过程中也要付出相当大的代价。

那么应该如何做呢?
作为一个正在努力脱离码农的程序员,我在这里提供一个思路:抽象出这些规则,在不同的地方引用这些规则

代码

首先,对于要对输入的内容进行监听,我们用TextWatcher接口。用一个类VipTextWatcher实现这个接口

public class VipTextWatcher implements TextWatcher{
    protected EditText editText;
    protected VipInputable callback;

    public VipTextWatcher(EditText editText, VipInputable callback) {
        this.editText = editText;
        this.callback = callback;
        editText.setInputType(InputType.TYPE_CLASS_PHONE);
    }

    @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) {
    }

    /**
     * 验证输入位数是否满足规则
     * @return
     */
    protected boolean validate() {
        return false;
    }
}

从上面的代码可以看出,类VipTextWatcher有两个属性(editText 和 callback),eidtText是要绑定规则EditText, callback是一个接口,用于做输入后是否让按钮可点击的判断 。

public interface VipInputable {
    void afterInput();
}

下面我们来编写手机号规则类PhoneNumTextWatcher

public class PhoneNumTextWatcher extends VipTextWatcher {
    public PhoneNumTextWatcher(EditText editText, VipInputable callback) { 
       super(editText, callback);
    } 
   @Override
    public void afterTextChanged(Editable editable) {
        editText.removeTextChangedListener(this);
        String value = editable.toString().replace(" ", "");
        for (int i = editable.length() - 1; i >= 0; i--) {
            if (editable.charAt(i) == ' ') {
                editable.delete(i, i + 1);
            }
        }
        try {
            if (value.length() >= 4) {
                if (editable.charAt(3) != ' ') {
                    editable.insert(3, " ");
                }
            }
            if (value.length() >= 8) {
                if (editable.charAt(8) != ' ') {
                    editable.insert(8, " ");
                }
            }
            if (value.length() >= 12) {
                if (editable.charAt(13) != ' ') {
                    editable.delete(13, editable.length());
                }
            }
        } catch (Exception e) {
            Log.e("" + getClass(), e.toString());
        }

        editText.addTextChangedListener(this);

        if (callback != null) {
            callback.afterInput();
        }
    }
    @Override
    protected boolean validate() {
        String phoneNum = editText.getText().toString().trim().replaceAll(" ", "");
        return phoneNum.length() == 11;
    }
}

这里只用重写父类 VipTextWatcher里面的两个方法afterTextChanged()validate()就可以了。
身份证号码规则类CardNumTextWatcher和银行卡号规则类IDNumTextWatcher也是类似,不做赘述。

最终在使用的时候,代码如下

public class MainActivity extends Activity {
    private EditText etPhoneNum;
    private EditText etCardNum;
    private EditText etIDNum;
    private Button btnSubmit;

    private VipTextWatcher phoneNumTextWatcher, cardNumTextWatcher, idNumTextWatcher;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etPhoneNum = (EditText) findViewById(R.id.etPhoneNum);
        etCardNum = (EditText) findViewById(R.id.etCardNum);
        etIDNum = (EditText) findViewById(R.id.etIDNum);
        btnSubmit = (Button) findViewById(R.id.btnSubmit);
        btnSubmit.setEnabled(false);

        initTextWatcher();
    }

    private void initTextWatcher() {
        //初始化手机号码输入监听器
        phoneNumTextWatcher = new PhoneNumTextWatcher(etPhoneNum, new VipInputable() {
            @Override
            public void afterInput() {
                btnSubmit.setEnabled(getSubmitBtnEnable());
            }
        });
        etPhoneNum.addTextChangedListener(phoneNumTextWatcher);

        //初始化银行卡号输入监听器
        cardNumTextWatcher = new CardNumTextWatcher(etCardNum, new VipInputable() {
            @Override
            public void afterInput() {
                btnSubmit.setEnabled(getSubmitBtnEnable());
            }
        });
        etCardNum.addTextChangedListener(cardNumTextWatcher);

        //初始化身份证号输入监听器
        idNumTextWatcher = new IDNumTextWatcher(etIDNum, new VipInputable() {
            @Override
            public void afterInput() {
                btnSubmit.setEnabled(getSubmitBtnEnable());
            }
        });
        etIDNum.addTextChangedListener(idNumTextWatcher);
    }

    private boolean getSubmitBtnEnable() {
        return phoneNumTextWatcher.validate() && cardNumTextWatcher.validate() && idNumTextWatcher.validate();
    }
}

xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:gravity="center_vertical">
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="手机号" />
        <EditText
            android:id="@+id/etPhoneNum"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"></EditText>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:gravity="center_vertical">
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="身份证号" />
        <EditText
            android:id="@+id/etIDNum"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"></EditText>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:gravity="center_vertical">
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="银行卡号" />
        <EditText
            android:id="@+id/etCardNum"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="5"></EditText>
    </LinearLayout>

    <Button
        android:id="@+id/btnSubmit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="提  交" />
</LinearLayout>

欢迎批评指正 ~

相关文章

网友评论

      本文标题:输入框验证

      本文链接:https://www.haomeiwen.com/subject/hveupttx.html