Tengo una lista de objetos en Recyclerview . Al presionar prolongadamente un elemento, quiero mostrar un cuadro de diálogo con datos del elemento en el que se hizo clic.
El Recyclerview está utilizando el enlace de datos para cada elemento y puedo mostrar los datos del elemento seleccionado usando Registro cuando presiono prolongadamente.
Sin embargo, al intentar mostrar un cuadro de diálogo, debe acceder a Activity , que no se recomienda usar en el objeto ViewModel .
Entonces, ¿cómo puedo mostrar el diálogo?
Gracias, Ove
Conceptualmente, un ViewModel me parece el lugar equivocado para iniciar un diálogo. Para hacerlo de manera más limpia, pasaría RecyclerView.ViewHolder al diseño y tendría un método en ViewHolder que active un oyente personalizado en su RecyclerView.Adapter. Luego, quien se suscriba a ese oyente (Actividad/Fragmento) puede iniciar el Diálogo. Puede parecer un poco indirecto, pero no creo que un ViewModel de un elemento de la lista deba tener conocimiento o control de su entorno.
Aquí hay un ejemplo. Este es un patrón general para manejar clics en elementos de RecyclerView con enlace de datos y un modelo de vista. Este no es un ejemplo completo, solo el código para resaltar este patrón específico.
Diseño:
<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>Adaptador:
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); } } } }Consulte la sección Variables de la documentación oficial de Data Binding Library. Allí encontrará un context variable que puede usar.
Se genera una variable especial denominada context para usarla en expresiones vinculantes según sea necesario. El valor de contexto es el contexto de
getContext()de la vista raíz. La variable de contexto será anulada por una declaración de variable explícita con ese nombre.
Básicamente, podría simplemente pasarlo a otra variable como viewModel para mostrar el cuadro de diálogo desde allí.
android:onClick="@{v -> viewModel.showDialog(context)}"Creo que usar un adaptador de enlace para una vista de reciclador y poner el adaptador en ViewModel, luego hacer que el modelo de vista sea el modelo de fragmento y pasar el adaptador para el método setAdapter en xml mismo.