输入框验证
2016-11-21 本文已影响88人
爱吃豆腐面
问题描述
最近做需求时,遇到过几次需要写一个页面,页面上要求用户输入诸如手机号、身份证号、银行卡号这类信息,还有一个提交按钮,每个输入框有特定的输入规则。
初始状态下,输入框里没有内容,提交按钮不能点击;当所有输入框里有输入了内容且满足输入规则时,按钮自动变为可点击状态。
输入规则
手机号规则
- 手机号输入必须是11位
- 采用3-3-4的输入样式,中间自动加入空格(133 6666 6666)
- 输入必须全为数字
身份证号规则
- 身份证号输入15位或者18位
- 采用6-4-4-4的输入样式(420923 1992 0202 2222)
- 输入必须全为数字
银行卡号规则
- 银行卡号输入位数必须在8到20位之间,包括8和20
- 采用4位一隔的输入样式(6226 2205 0598 6666)
- 输入必须全为数字
思路分析
作为码农,很容易为做需求而做需求,在每个地方写上了大量相同的代码逻辑判断,虽然程序运行上没有问题,也完全符合需求,但是如果你真的这样做,那你就真的是个码农啦!因为简单的复制粘贴是最低级的,也是最易错和难改的,在后期的维护过程中也要付出相当大的代价。
那么应该如何做呢?
作为一个正在努力脱离码农的程序员,我在这里提供一个思路:抽象出这些规则,在不同的地方引用这些规则
代码
首先,对于要对输入的内容进行监听,我们用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>
欢迎批评指正 ~