当我有一个自定义对象时,我遇到了一些数据绑定和实时数据的问题。
例如:
我有MutableLiveData
val user = MutableLiveData<User>()
并且我正在使用双向数据绑定 @={viewModel.user.name}
但是我的观察者它没有在碎片内部被解雇 viewModel.user.observer
.
当我在生成的类中放置断点FragmentBinding
时,我可以看到 setValue 被调用以及 userLiveData 的用户值和数据。
问题是观察者没有在碎片中被触发。
有人知道我在那里做错了什么吗?
编辑 1
下面是我的片段代码:
val infoPessoalViewModel: InfoPessoalViewModel by viewModel()
lateinit var bindingView: FragmentInfoPessoalBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
bindingView = DataBindingUtil.inflate(inflater, R.layout.fragment_info_pessoal, container, false)
return bindingView.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
bindingView.apply {
lifecycleOwner = this@InfoPessoalFragment
viewModel = infoPessoalViewModel
}
infoPessoalViewModel.user.observe(this, Observer { user ->
user.confirmEmail?.let {
//NOT FIRED HERE
Log.d("LiveData","Fired!")
}
})
}
编辑 2
抱歉,我给出了一个带有差异名称的示例变量。
您的 BindingAdapter 逻辑应该能够EditText
输入转换为User
实例,反之亦然。假设User
实例如下所示:
用户.kt
class User(val username: String)
那么一个示例适配器应该是:
MyBindingAdapters.kt
/**
* Convert EditText input into a User instance.
*/
@InverseBindingAdapter(attribute = "android:text")
fun getUser(view: EditText): User {
return User(view.text.toString())
}
/**
* Convert a User instance into EditText text
*/
@BindingAdapter("android:text")
fun setUser(view: EditText, newUser: User?) {
if (newUser?.username != view.text.toString()) {
view.setText(newUser?.username)
}
}
在布局文件中,绑定到userLiveData
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={viewModel.userLiveData}"/>
请注意适配器是双射的,这意味着一个User
正好与一个String
配对,反之亦然。如果类User
更复杂,那么与MutableLiveData<User>
的双向绑定实际上没有意义。在这种情况下,您应该将其绑定到MutableLiveData<String>
,并手动更新视图模型中User
实例。