android实用技术Android开发经验谈Android开发

利用观察者模式对按钮进行封装

2018-01-18  本文已影响85人  吴蜀黍

业务需求如下

传统做法

...
    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>
    ...
    /**
     * 存放被观察者(输入框)
     */
    private List<EditText> edtTextList = new ArrayList<>();
    ...

    /**
     * 观察方法
     *
     * @param editTexts 被观察者
     */
    public void observer(EditText... editTexts) {
        //遍历所有的et
        for (EditText et : editTexts) {
            et.addTextChangedListener(this);
            edtTextList.add(et);
        }
    }
    ...
   @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);
        }
    }
    btnRegister.observer(edtName, edtPwd, edtAge);

最后,放一张我家的小奶猫,哈哈!

小奶猫.jpg
上一篇 下一篇

猜你喜欢

热点阅读