从 ViewModel 启动 DialogFragment 的推荐方法是什么?

2022-09-04 20:48:57

我在 .长按某个项目时,我想显示一个对话框,其中包含所单击项目的数据。Recyclerview

正在对每个项目使用数据绑定,并且能够在长按时使用 Log 显示所选项目中的数据。Recyclerview

但是,在尝试显示对话框时,需要转到 ,不建议在对象中使用 。ActivityViewModel

那么如何显示对话框呢?

谢谢,欧维


答案 1

从概念上讲,ViewModel在我看来是启动对话框的错误位置。为了更干净地做到这一点,我会将 RecyclerView.ViewHolder 传递到布局中,并在 ViewHolder 上有一个方法,该方法在 RecyclerView.Adapter 上触发自定义侦听器。然后,订阅该侦听器(活动/片段)的任何人都可以启动对话框。可能看起来有点迂回,但我不认为列表项的ViewModel应该了解或控制其环境。

下面是一个示例。这是使用数据绑定和 ViewModel 处理 RecyclerView 项目单击的常规模式。这不是一个完整的示例,只是突出显示此特定模式的代码。

布局:

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <data>
    <variable
        name="viewHolder"
        type="com.example.ViewHolder"
        />
    <variable
        name="viewModel"
        type="com.example.ViewModel"
        />
    </data>

    <com.example.View
        android:layout_width="match_parent"
        android:layout_height="24dp"
        android:onClick="@{() -> viewHolder.onClick(viewModel)}"
        />
</layout>

适配器:

class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    public interface SelectionListener {
        void onSelectionChanged(int newPosition, ViewModel viewModel);
    }

    private @NonNull WeakReference<SelectionListener> selectionListener =
            new WeakReference<>(null);

    public void setSelectionListener(@Nullable SelectionListener listener) {
        selectionListener = new WeakReference<>(listener);
    }

    public class ViewHolder extends RecyclerView.ViewHolder<ViewBinding> {
        ViewHolder(ViewBinding binding) {
            super(binding.getRoot());

            binding.setViewHolder(this);
            binding.setViewModel(new ViewModel());
        }

        public void onClick(ViewModel viewModel) {
            SelectionListener listener = selectionListener.get();
            if (listener != null) {
                listener.onSelectionChanged(getAdapterPosition(), viewModel);
            }
        }
    }
}

答案 2

请参阅数据绑定库的官方文档的“变量”部分。在那里,您可以找到一个可以使用的变量。context

将生成一个名为 context 的特殊变量,以便根据需要在绑定表达式中使用。上下文的值是根视图的 上下文中的 。上下文变量将被具有该名称的显式变量声明覆盖。getContext()

基本上,您可以将其传递给另一个变量,例如从那里显示对话框。viewModel

android:onClick="@{v -> viewModel.showDialog(context)}"

推荐