Dan*_*obs 2 android android-fragments kotlin android-databinding android-viewmodel
ViewModel我想在单击按钮时使用带有数据绑定的复选框来禁用复选框,但除非片段被销毁并重新创建,否则 UI 不会更新。
似乎有很多类似的问题,但最相似的问题似乎都可以通过设置来解决binding.lifecycleOwner,我已经完成了。
片段_复选框_数据绑定.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".CheckboxDatabindingFragment">
    
    <data>
        <variable
            name="viewModel"
            type=".CheckboxDatabindingFragmentViewModel" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <CheckBox
            android:id="@+id/my_checkbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:enabled="@{viewModel.checkboxEnabled}" />
        <Button
            android:id="@+id/my_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> viewModel.startClicked()}" />
    
    </LinearLayout>
</layout>
CheckboxDatabindingFragment.kt:
class CheckboxDatabindingFragment() : Fragment() {
    private lateinit var viewModel: CheckboxDatabindingFragmentViewModel
    private var _binding: FragmentCheckboxDatabindingBinding? = null
    private val binding get() = _binding!!
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        viewModel = ViewModelProvider(this).get(CheckboxDatabindingFragmentViewModel::class.java )
        
        _binding = FragmentCheckboxDatabindingBinding.inflate(inflater, container, false)
        binding.lifecycleOwner = viewLifecycleOwner // androidx.fragment.app.FragmentViewLifecycleOwner
        binding.viewModel = viewModel
        
        return binding.root
    }
    ...
}
CheckboxDatabindingFragmentViewModel.kt:
class CheckboxDatabindingFragmentViewModel(application: Application) : AndroidViewModel(application) {
    var checkboxEnabled = true
    fun startClicked() {
        checkboxEnabled = false
    }
}
CheckboxDatabindingFragment.kt我知道我可以通过手动获取复选框视图并设置属性来轻松执行此功能isEnabled,但这违背了数据绑定的目的。
我需要片段而不是活动作为所有者,那么如何更新片段 UI?
var checkboxEnabled = true
top 语句创建一个不可观察的布尔值,因此无法观察到该变量的任何更改,也无法通过生命周期所有者(在您的情况下是片段)将其提交到布局。
设置用于观察此绑定中 LiveData 变化的 LifecycleOwner。如果 LiveData 位于绑定表达式之一中并且未设置 LifecycleOwner,则不会观察到 LiveData,并且对其的更新也不会传播到 UI。
因此,binding.lifecycleOwner = viewLifecycleOwner单独使用不足以通过数据绑定发布对布局的更改,还必须使用可以被 lifeCycleOwner 观察到的可观察对象,并最终通过 DataBinding 将它们的任何更改发布到布局。
要解决这个问题,您需要将 更改checkboxEnabled为可观察的:
选项 1:使用ObservableBoolean:
class CheckboxDatabindingFragmentViewModel(application: Application) : AndroidViewModel(application) {
    val checkboxEnabled = ObservableBoolean(true)
    fun startClicked() {
        checkboxEnabled.set(false)
    }
}
选项 2:使用MutableLiveData:
class CheckboxDatabindingFragmentViewModel(application: Application) : AndroidViewModel(application) {
    val checkboxEnabled = MutableLiveData(true)
    fun startClicked() {
        checkboxEnabled.value = false
    }
}
| 归档时间: | 
 | 
| 查看次数: | 1132 次 | 
| 最近记录: |