业务需求如下
- 功能需求:用户注册。
-
期望效果:用户必须输入用户名、密码、年龄,注册按钮方可点击。
图片.png
传统做法
...
protected void initView() {
edtName.addTextChangedListener(new MyTextWatcher() {
@Override
public void afterTextChanged(Editable s) {
observationEditText();
}
});
edtPwd.addTextChangedListener(new MyTextWatcher() {
@Override
public void afterTextChanged(Editable s) {
observationEditText();
}
});
edtAge.addTextChangedListener(new MyTextWatcher() {
@Override
public void afterTextChanged(Editable s) {
observationEditText();
}
})
/**
* 对输入框的输入观察
*/
private void observationEditText() {
String name = edtName.getText().toString().trim();
String pwd = edtPwd.getText().toString().trim();
String age = edtAge.getText().toString().trim();
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd) || TextUtils.isEmpty(age)) {
btnRegister.setEnabled(false);
btnRegister.setBackgroundColor(Color.GRAY);
} else {
btnRegister.setEnabled(true);
btnRegister.setBackgroundColor(Color.GREEN);
}
}
/**
* 简单实现 TextWatcher接口
*/
abstract class MyTextWatcher implements 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) {
}
}
...
如此做法固然可以实现上面的需求,也能达到预期效果,但总体看起来,代码量多,不易维护,扩展性也差;如果再多几个输入框,又要写一堆的文本框输入监听等等。开发的时候一旦发现需要写大量重复的代码的时候,那么一定还有更优的方案,所以我们衍生出下面的处理方式。
升级做法
分析:在这个需求中,我们的按钮充当着观测者的角色,而输入框则是被观察者,一旦输入框有了变化按钮就要做出相应的反应,这正好满足设计模式中观测者模式的设计理念,所以我们可以把按钮进行封装,提供一个可供外部调用的观察方法,具体做法如下:
- 自定义几个控制按钮背景色和文字颜色的属性
<declare-styleable name="ObserverButton">
<!--默认背景-->
<attr name="defaultBg" format="color|reference" />
<!--可以点击的背景-->
<attr name="pressBg" format="color|reference" />
<!--默认字体颜色-->
<attr name="defaultTextColor" format="color" />
<!--可以点击的字体颜色-->
<attr name="pressTextColor" format="color" />
</declare-styleable>
- 2.提供观察方法
...
/**
* 存放被观察者(输入框)
*/
private List<EditText> edtTextList = new ArrayList<>();
...
/**
* 观察方法
*
* @param editTexts 被观察者
*/
public void observer(EditText... editTexts) {
//遍历所有的et
for (EditText et : editTexts) {
et.addTextChangedListener(this);
edtTextList.add(et);
}
}
- 3.在输入结束的时候遍历所有被观察者
...
@Override
public void afterTextChanged(Editable s) {
checkEditText();
}
/**
* 检查输入框输入
*/
private void checkEditText() {
canPress = true;
for (EditText et : edtTextList) {
if (TextUtils.isEmpty(et.getText().toString().trim())) {
canPress = false;
break;
}
}
initBtn();
}
private void initBtn() {
if (canPress) {
setTextColor(pressTextColor);
setBackgroundColor(pressBg);
setEnabled(true);
} else {
setTextColor(defaultTextColor);
setBackgroundColor(defaultBg);
setEnabled(false);
}
}
- 4.调用,一行代码足以!
btnRegister.observer(edtName, edtPwd, edtAge);
网友评论