从 ViewModel 启动 DialogFragment 的推荐方法是什么? [英] What is the recommended way to launch a DialogFragment from a ViewModel?
问题描述
我在 Recyclerview
中有一个列表对象.长按某个项目时,我想显示一个对话框,其中包含所点击项目的数据.
I have a list objects in a Recyclerview
. When long-pressing an item I want to show a dialog with data from the item clicked.
Recyclerview
为每个项目使用数据绑定,我可以在长按时使用 Log 显示所选项目的数据.
The Recyclerview
is using data binding for each item and I am able to display data from the selected item using Log when long-pressing.
但是,当尝试显示对话框时,您需要访问 Activity
,不推荐在 ViewModel
对象中使用.
When trying to show a dialog, however, you need to get to the Activity
, which is not recommended to use in the ViewModel
object.
那么如何显示对话框?
谢谢欧维
推荐答案
从概念上讲,我认为 ViewModel 是启动 Dialog 的错误位置.为了更干净地做到这一点,我会将 RecyclerView.ViewHolder 传递到布局中,并在 ViewHolder 上有一个方法来触发 RecyclerView.Adapter 上的自定义侦听器.然后订阅该侦听器(活动/片段)的任何人都可以启动对话框.可能看起来有点迂回,但我认为列表项的 ViewModel 不应该了解或控制其环境.
Conceptually a ViewModel strikes me as the wrong place to launch a Dialog from. To do it more cleanly I would pass the RecyclerView.ViewHolder into the layout, and have a method on the ViewHolder that triggers a custom listener on your RecyclerView.Adapter. Then whoever subscribes to that listener (Activity/Fragment) can launch the Dialog. May seem a little roundabout, but I don't think a ViewModel of a list item should have knowledge or control of its environment.
这是一个例子.这是使用数据绑定和 ViewModel 处理 RecyclerView 项目点击的通用模式.这不是一个完整的示例,只是突出显示此特定模式的代码.
Here is an example. This is a general pattern for handling RecyclerView item clicks with data binding and a ViewModel. This is not a complete example, just the code to highlight this specific pattern.
布局:
<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);
}
}
}
}
这篇关于从 ViewModel 启动 DialogFragment 的推荐方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!