【发布时间】:2019-02-01 15:35:21
【问题描述】:
当 4 个 EditText 的字符数超过 X 并且电子邮件有效时(忽略 xml,仍在应用样式),我正在尝试启用/禁用按钮:
<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 如果至少有 1 个观察者,请查看代码:
在我的视图模型上:
//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
}
在我的片段上:
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 有对 View (LifecycleOwner) 的引用,是的,我可以将空观察者放在 Fragment 上,不需要将 LifecycleOwner 传递给 ViewModel 但仍然感觉不对,也许我在这里有点完美主义,但我敢打赌,还有另一种直接从 ViewModel 绑定的方法,而不必设置 isEnable 观察 Fragment 中的 MediatorLiveData?
谢谢!
【问题讨论】:
-
你不需要
createAccountDetailsValid.observe(owner, Observer { }) -
@Blackbelt 是的,我需要因为这个
@MainThread public <S> void addSource(@NonNull LiveData<S> source, @NonNull f (existing != null) { return; } if (hasActiveObservers()) { e.plug(); } }基本上,它没有任何观察者,正如你所看到的那样,我需要一个观察者,所以我需要一个奇怪的原因。 -
你不需要那个。
databinding会为你观察。中介者是一个LiveData对象。您是否需要为您拥有的每个LiveData对象添加Observe? -
我也是这么想的,但是如果我删除了观察绑定停止工作,也许我在这里做错了什么。
-
是的,它正在工作,可能做错了什么并最终通过复杂化来修复,它只是按照我从一开始就认为的方式工作,感谢您的帮助伙伴!
标签: android kotlin android-databinding android-livedata