数据绑定和 MVVM。通过单击按钮显示 DatePickerDIalog

Data binding & MVVM. Show DatePickerDIalog by clicking on the button

现在我有了这个代码:

class MyFragment : DaggerFragment() {
    ...
    private fun setTimePickerDialog() {
        binding.timeButton.setOnClickListener{
            val calendar = viewModel.calendar
            val curHourOfDay = calendar.get(Calendar.HOUR_OF_DAY)
            val curMinute = calendar.get(Calendar.MINUTE)
            val dialog = TimePickerDialog(context, { _, hourOfDay, minute ->
                 val c = Calendar.getInstance()
                 c.set(1970, 0, 1, hourOfDay, minute)
                 viewModel.time.value = SimpleDateFormat("HH:mm:ss").format(c.time)
            }, curHourOfDay, curMinute, true)
            dialog.show()
        }
    }
    ...
}

我想利用 DataBinding 库,而不是在我的片段中写入 setOnClickListener。但我无法将此代码移至 ViewModel,因为需要上下文。通过使用 DataBinding 和 MVVM 单击按钮来显示 DatePickerDialog 的简洁方法是什么?

您正在寻找的东西,可以使用架构组件中的 LiveData 来实现,也可以使用任何其他可观察工具(例如 rxJava)来完成。

第一步是在我们的 ViewModel 中定义一个可观察对象,并实现一个函数,当用户点击时,它会调用该可观察对象。

ViewModel:

MutableLiveData<Boolean> timePickerDialogData = new MutableLiveData<>();
...

public void onDisplayTimePickerDialogClick() {
    timePickerDialogData.setValue(true);
}

...
public LiveData<Boolean> getTimePickerDialogData() {
        return timePickerDialogData;
    }

第二步,观察fragment中的observable,监听它的值变化。当从 ViewModel 调用 observable 时,我们可以显示对话框。

片段:

private void observeTimePickerDialogData() {
    viewModel.getTimePickerDialogData().observe(this, display -> {
    if(display) setTimePickerDialog(); // Display TimePickerDialog
    });
}

最后,XML 布局文件中的 onClick 逻辑使用 android 数据绑定。

XML:

android:onClick="@{()->viewModel.onDisplayTimePickerDialogClick()}"

为什么不能在 xml 中使用处理程序而不是视图模型。然后使用处理程序获取点击。 在你的 XML --> 使用一个名为 handler 的变量,其类型是你的片段的路径

<data class ="binding">
    <variable name="handler" type="com.MyFragment"/>
</data>

android:onClick="@{()->handler.onDisplayTimePickerDialogClick()}

我认为可以通过 ViewModel 上的 onClickMethod 更直接地完成。通过将视图作为参数传递给 onClick-Method,我们可以使用视图的上下文来启动 TimePickerDialog:

我的可点击 TextView 如下所示(仅包含相关属性):

    <TextView
        android:onClick="@{(view) -> viewmodel.onChangeTimeClicked(view)}"/>

我的 ViewModel 的 onClicked-Method 看起来像这样:

    fun onChangeTimeClicked(v: View) {
        val timeSetListener = TimePickerDialog.OnTimeSetListener { _,_,_ ->
            // Some Implementation
        }
        TimePickerDialog(
            v.context,          // <-- Context from view on which was clicked
            timeSetListener,
            0,
            0,
            true
        ).show()
    }

我知道这个问题有点老了,但由于我现在遇到了这个问题,所以我找到了这个帖子,也许它对某些人仍然有用。