首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MediatorLiveData直接从ViewModel绑定到视图

MediatorLiveData直接从ViewModel绑定到视图
EN

Stack Overflow用户
提问于 2019-02-01 15:35:21
回答 1查看 2K关注 0票数 0

当4个EditTexts有超过X个字符且电子邮件是有效的时,我试图启用/禁用一个按钮(忽略xml,仍然应用样式):

代码语言:javascript
复制
  <Button
            android:id="@+id/fragment_login_button"
            android:fontFamily="@font/montserrat_regular"
            android:layout_marginTop="20dp"
            android:textColor="@android:color/white"
            android:background="@drawable/button_primary"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:enabled="@{viewModel.createAccountDetailsValid}"
            android:layout_marginRight="20dp"
            android:text="create account "
            android:onClick="@{(theView) -> handler.onCreateClick(theView, viewModel)}"
            app:layout_constraintTop_toBottomOf="@id/fragment_login_companyText"
    />

我让它使用MediatorLiveData和按钮所依赖的4 MutableLiveData来工作,但是我发现通过这样做可以使违背MVVM标准,但这是唯一的工作方式,因为MediatorLiveData只允许addSource (如果至少有一个观察者),请查看代码:

关于我的观点模型:

代码语言:javascript
复制
//USER DATA
val email: MutableLiveData<String> = MutableLiveData()
val name: MutableLiveData<String> = MutableLiveData()
val surname: MutableLiveData<String> = MutableLiveData()
val company: MutableLiveData<String> = MutableLiveData()
val createAccountDetailsValid: MediatorLiveData<Boolean> = MediatorLiveData()

fun populateMediator(owner: LifecycleOwner) {
        createAccountDetailsValid.observe(owner, Observer {  })
        createAccountDetailsValid.addSource(email) {
            createAccountDetailsValid.value = isCreateAccountDetailsValid()
        }
        createAccountDetailsValid.addSource(name) {
            createAccountDetailsValid.value = isCreateAccountDetailsValid()
        }
        createAccountDetailsValid.addSource(surname) {
            createAccountDetailsValid.value = isCreateAccountDetailsValid()
        }
        createAccountDetailsValid.addSource(company) {
            createAccountDetailsValid.value = isCreateAccountDetailsValid()
        }
    }

private fun isCreateAccountDetailsValid() : Boolean {
    if(email.value == null || name.value == null || surname.value == null || company.value == null) return false
    return android.util.Patterns.EMAIL_ADDRESS.matcher(email?.value!!).matches() && name.value?.length!! >= 3 && surname.value?.length!! >= 3 && company.value?.length!! >= 3
}

在我的碎片上:

代码语言:javascript
复制
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_login, container,false)
    viewModel = ViewModelProviders.of(this, viewModelFactory).get(LoginViewModel::class.java)
    binding.viewModel = viewModel
    binding.handler = LoginHandler()
    binding.setLifecycleOwner(this)
    viewModel.setLifecycleOwner(this as LifecycleOwner)
    return binding.root
}

就像我说的那样,ViewModel对视图( LifecycleOwner )有一个引用,是的,我可以将空的观察者放在片段上,不需要将LifecycleOwner传递给ViewModel,但仍然感觉不太好,也许我在这里有点完美主义,但我敢打赌还有另一种方式可以直接从ViewModel绑定,而不必在片段中设置isEnable来观察MediatorLiveData?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-01 16:14:10

有黑带的评论,我应该做错了什么,结果是复杂和解决问题,同时试图使它发挥作用。

他说过,数据绑定观察到了,您可以像我一样在addSource init上使用viewModel init,并使其正常工作:

代码语言:javascript
复制
 val createAccountResult: MutableLiveData<Resource<Void>> = MutableLiveData()
val loginResult: MutableLiveData<Resource<Void>> = MutableLiveData()

//USER DATA
val email: MutableLiveData<String> = MutableLiveData()
val name: MutableLiveData<String> = MutableLiveData()
val surname: MutableLiveData<String> = MutableLiveData()
val company: MutableLiveData<String> = MutableLiveData()

var createAccountDetailsValid: MediatorLiveData<Boolean> = MediatorLiveData()

init {
    createAccountDetailsValid.addSource(email) {
        createAccountDetailsValid.value = isCreateAccountDetailsValid()
    }
    createAccountDetailsValid.addSource(name) {
        createAccountDetailsValid.value = isCreateAccountDetailsValid()
    }
    createAccountDetailsValid.addSource(surname) {
        createAccountDetailsValid.value = isCreateAccountDetailsValid()
    }
    createAccountDetailsValid.addSource(company) {
        createAccountDetailsValid.value = isCreateAccountDetailsValid()
    }
}

谢谢你的帮助@黑带

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54482575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档