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

时间:2018-10-27 18:14:39

标签: android mvvm android-databinding android-architecture-components

现在我有了以下代码:

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的干净方法是什么?

3 个答案:

答案 0 :(得分:3)

为什么不能在xml中而不是viewmodel中使用处理程序。然后使用处理程序获得点击。 在XML中->使用一个称为处理程序的变量,其类型是片段的路径

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

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

答案 1 :(得分:0)

您要查找的内容可以使用体系结构组件中的LiveData来实现,也可以使用任何其他可观察到的工具(例如rxJava)来实现。

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

ViewModel:

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

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

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

第二步是观察片段中的可观察对象并听其值变化。当ViewModel中调用observable时,我们可以显示该对话框。

片段:

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

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

XML:

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

答案 2 :(得分:0)

我认为可以使用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()
    }

我知道这个问题有点老了,但是由于我现在遇到了这个问题,我发现了这个线程,也许它对某些人还是有用的。