在Android上重构观察者

时间:2020-08-03 19:26:53

标签: android kotlin android-livedata android-mvvm

我正在构建一个应用程序,我创建了一个带有两个输入文本和一个用于发送消息的按钮的联系人类型页面。现在,我想仅在满足某些条件时才启用该按钮,这些条件是三个最重要的字段填充有某些数据(服务,对象和消息)。

使用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()
                })
            })
        })

基本上,它的作用是检查三个字段是否充满数据,如果是这种情况,它将激活按钮,效果很好。

但是我的问题是:它是一个嵌套的观察者,甚至是两倍。那么,是否有可能让它看起来更干净而无需嵌套的观察者来检查条件是否满足?

谢谢。

1 个答案:

答案 0 :(得分:1)

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

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

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模式,那么这仍然很糟糕,因为您在视图中执行逻辑。 MVVM 100%正确的是为您的viewmodel提供单个livedata变量,该变量告诉视图是否启用按钮。然后,唯一的观察者和唯一正在做的事情应该看起来像这样:

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