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

作者: 吴蜀黍 | 来源:发表于2018-01-18 14:02 被阅读85次

业务需求如下

  • 功能需求:用户注册。
  • 期望效果:用户必须输入用户名、密码、年龄,注册按钮方可点击。


    图片.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) {

        }

    }
...

如此做法固然可以实现上面的需求,也能达到预期效果,但总体看起来,代码量多,不易维护,扩展性也差;如果再多几个输入框,又要写一堆的文本框输入监听等等。开发的时候一旦发现需要写大量重复的代码的时候,那么一定还有更优的方案,所以我们衍生出下面的处理方式。

升级做法

分析:在这个需求中,我们的按钮充当着观测者的角色,而输入框则是被观察者,一旦输入框有了变化按钮就要做出相应的反应,这正好满足设计模式中观测者模式的设计理念,所以我们可以把按钮进行封装,提供一个可供外部调用的观察方法,具体做法如下:

    1. 自定义几个控制按钮背景色和文字颜色的属性
    <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);

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

小奶猫.jpg

相关文章

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

    业务需求如下 功能需求:用户注册。 期望效果:用户必须输入用户名、密码、年龄,注册按钮方可点击。图片.png 传统...

  • 用静态工厂来封装retrofit

    用静态工厂来封装retrofit 利用反射机制和静态工厂模式,对retrofit进行简单的封装 利用反射机制,动态...

  • Jetpack 全局控制 实战自定义Toast

    自定义Toast 控制Toast 的位置 利用LiveData 观察者模式,封装到BaseActivity观察。L...

  • js 观察者模式

    观察者模式的封装

  • 对AFNetworking进行简单的封装

    如题利用单例模式对AFNetworking进行简单的封装(仅仅是封装了最基本的GET,POST请求)。供新手使用。...

  • 观察者模式二

    简述 有对观察者模式不清楚的朋友请先查看 观察者模式一 本文利用观察者模式设计一个乘客收到火车到站通知上车和下车...

  • 中介者模式

    观察者与订阅/发布模式的区别 1.观察者模式中观察者必须对主题进行订阅后,才能收到主题的事件。 2.订阅/发布模式...

  • 观察者模式和发布订阅模式的区别

    1.模式差异 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订...

  • 观察者模式

    2020.01.13 晚 22:43 问题 我们从下面3个问题去对观察者模式进行探讨 为什么需要观察者模式? 观察...

  • RXSwift笔记

    观察者模式:KVO、通知 被观察者:发出一个事件 观察者/订阅者:对被观察者对象进行响应 RXSwift:把程序中...

网友评论

  • 蒲导:观察者模式是观察者有多个对象, 被观察唯一,类似订阅系统.你这个概念有点模糊
    吴蜀黍:嗯嗯 是的 似乎在概念上俩反了 理解还不是很透彻

本文标题:利用观察者模式对按钮进行封装

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