在 Android 上重构 Observer

Refactoring Observer on Android

我正在构建一个应用程序,我制作了一个联系人类型页面,其中包含几个输入文本和一个用于发送消息的按钮。现在,我只想在满足某些条件时才启用按钮,这三个最重要的字段填充了一些数据(服务、对象和消息)。

使用 MVVM 模式和双向数据绑定,它工作得很好,但是当我观察视图链接到的片段中的数据时,我有一些丑陋的代码,如下所示:

contactPageViewModel.serviceToContact.observe(viewLifecycleOwner, Observer { service ->
            contactPageViewModel.objectContact.observe(viewLifecycleOwner, Observer { objectContact ->
                contactPageViewModel.message.observe(viewLifecycleOwner, Observer { message ->
                    contact_send_btn.isEnabled = !service.isNullOrEmpty() && !objectContact.isNullOrEmpty() && !message.isNullOrEmpty()
                })
            })
        })

基本上它所做的是检查这三个字段是否充满了数据,如果是的话,它会激活按钮,效果很好。

但我的问题是:它是一个嵌套的观察者,甚至是两次。那么,是否可以在没有嵌套观察者检查条件是否满足的情况下让它看起来更干净?

谢谢。

你永远不应该有嵌套的观察者。这不仅看起来很糟糕,而且是一个 大漏洞 ,因为每次触发外部观察者时,您都会重复创建重复的观察者。

另一种保持视图模型不变的方法是分离观察者并调用一个函数来更新每个观察者中的按钮。

contactPageViewModel.serviceToContact.observe(viewLifecycleOwner, Observer { service ->
    updateSendButtonEnabled()
})

contactPageViewModel.objectContact.observe(viewLifecycleOwner, Observer { objectContact ->
    updateSendButtonEnabled()
})

contactPageViewModel.message.observe(viewLifecycleOwner, Observer { message ->
    updateSendButtonEnabled()
})

fun updateSendButtonEnabled() {
    val service = contactPageViewModel.serviceToContact.value
    val objectContact = contactPageViewModel.objectContact.value
    val message = contactPageViewModel.message.value
    contact_send_btn.isEnabled = !service.isNullOrEmpty() && !objectContact.isNullOrEmpty() && !message.isNullOrEmpty()
}

但是!如果您想尽可能符合 MVVM 模式,这仍然很糟糕,因为您是在自己的视图中执行逻辑。 100% 符合 MVVM 是给你的视图模型一个单一的 livedata 变量,告诉视图是否启用按钮。那么唯一的观察者和它正在做的唯一事情应该是这样的:

contactPageViewModel.sendButtonEnabled.observe(viewLifecycleOwner, Observer { isEnabled ->
    contact_send_btn.isEnabled = isEnabled
})