MVVM - 如何干净地合并 AlertDialog?
MVVM - How to cleanly incorporate AlertDialog?
我有一个包含 MVVM 模式的 FragmentOne
。 Fragment
有自己的 ViewModel
、FragmentOneViewModel
。我不确定如何在我的案例中干净地合并 AlertDialog
。
在 Fragment 中它包含一个 RecyclerViewAdapter,每行包含一个 Button 以创建一个 AlertDialog。我需要 AlertDialog 的 ViewModel 吗?
或者我可以使用接口回调并在我的 Fragment 上实现它,当用户单击 AlertDialog 中的按钮时将调用它。然后使用该输入调用 Fragment 的 ViewModel?:
public class ActivateUserDialog extends AlertDialog {
//Should I use callback methods?
private Context mContext;
public interface DialogOnClickListener{
void onCancelBtnClick();
void onConfirmBtnClick(String amount);
}
public ActivateUserDialog(@NonNull Context context) {
super(context);
this.mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_activate);
ButterKnife.bind(this);
}
@OnClick(R.id.btn_cancel)
public void onBtnDismiss() {
this.dismiss();
}
@OnClick(R.id.btn_confirm)
public void onBtnConfirm() {
//Call the fragment
MainActivity activity = (MainActivity) mContext;
MembersFragment fragment = (MembersFragment) .... get the fragment;
fragment.onConfirmBtnClick(amount);
}
}
然后从回调方法中调用视图模型:
//Fragment class:
public class MembersFragment extends Fragment implements ActivateUserDialog.DialogOnClickListener
@Override
public void onConfirmBtnClick(String amount){
mViewModel.activateUser(amount);
}
这是一种干净的方法吗?
您想在 recycler-view adapter
中的某些点击上使用基于 MVVM 模式的 dialog box
,并希望在对话框操作后在适配器上进行一些 回调对吧?
Yes this is what I am doing in my code above, but I don't know if
this is the best practice way to do it with Dialog – DIRTY DAVE
因为我认为这是一个好方法 easy to understand
和 maintainable
。但是,dialog box
是 UI 的一部分,因此与它交互。所以它应该在片段中。然后与 view-model 交互的片段是一种可靠的做事方式,因为这是您逻辑的主要家园。
由于 MVVM 设计模式 与众所周知的 MVC 模式相似,因为 M(模型)和 V(视图)相对相同。唯一的区别在于 C(控制器)和 VM(视图模型)之间。
- 型号
表示数据+状态+业务逻辑。它既不绑定到视图也不绑定到控制器,这使得它可以在许多上下文中重用。
- 查看
绑定到视图模型公开的可观察变量和操作。多个视图可以绑定到单个视图模型。
- 查看模型
负责包装模型并准备视图所需的可观察数据。它还为视图提供挂钩以将事件传递给模型。需要牢记的重要一点是视图模型与视图无关。
我不认为对此只有一个答案,并且会说它是自以为是的。我认为两者都有效。
您还需要考虑到体系结构组件不能与 AlertDialogs 一起“开箱即用”,因此即使您想要它的 VM,您也必须通过 fragment/activity 检索它(基本上a ViewModelProvider) 或使用其他解决方案,如 DI。
您还必须管理 AlertDialog 的生命周期以获得 ViewModel 的一些好处。
以下是可能的解决方案:
- 将 AlertDialog 视为 FragmentOne 视图的一部分,并通过回调与其通信。在实现中与 FragmentOneViewModel 通信。
- 改用 DialogFragment 和 ViewModel。由于 DialogFragment 基本上只是一个片段,您可以获得架构组件 ViewModel 的所有好处。您可以在两者之间共享 FragmentOneViewModel 或创建专用于对话框的新 ViewModel。是共享还是创建一个新的取决于您的需要,但我会考虑对话框的复杂性以及它是否应该是独立的。如果您决定共享 ViewModel,请注意您使用的是哪个 ViewModelProvider 以确保它们实际上是共享的,而不是不同的实例。
至于从 AlertDialog 返回通信,我建议使用带回调的接口,而不是直接传递 Context 和强制转换。
您可以在构造函数中接受一个实现。
我有一个包含 MVVM 模式的 FragmentOne
。 Fragment
有自己的 ViewModel
、FragmentOneViewModel
。我不确定如何在我的案例中干净地合并 AlertDialog
。
在 Fragment 中它包含一个 RecyclerViewAdapter,每行包含一个 Button 以创建一个 AlertDialog。我需要 AlertDialog 的 ViewModel 吗?
或者我可以使用接口回调并在我的 Fragment 上实现它,当用户单击 AlertDialog 中的按钮时将调用它。然后使用该输入调用 Fragment 的 ViewModel?:
public class ActivateUserDialog extends AlertDialog {
//Should I use callback methods?
private Context mContext;
public interface DialogOnClickListener{
void onCancelBtnClick();
void onConfirmBtnClick(String amount);
}
public ActivateUserDialog(@NonNull Context context) {
super(context);
this.mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_activate);
ButterKnife.bind(this);
}
@OnClick(R.id.btn_cancel)
public void onBtnDismiss() {
this.dismiss();
}
@OnClick(R.id.btn_confirm)
public void onBtnConfirm() {
//Call the fragment
MainActivity activity = (MainActivity) mContext;
MembersFragment fragment = (MembersFragment) .... get the fragment;
fragment.onConfirmBtnClick(amount);
}
}
然后从回调方法中调用视图模型:
//Fragment class:
public class MembersFragment extends Fragment implements ActivateUserDialog.DialogOnClickListener
@Override
public void onConfirmBtnClick(String amount){
mViewModel.activateUser(amount);
}
这是一种干净的方法吗?
您想在 recycler-view adapter
中的某些点击上使用基于 MVVM 模式的 dialog box
,并希望在对话框操作后在适配器上进行一些 回调对吧?
Yes this is what I am doing in my code above, but I don't know if this is the best practice way to do it with Dialog – DIRTY DAVE
因为我认为这是一个好方法 easy to understand
和 maintainable
。但是,dialog box
是 UI 的一部分,因此与它交互。所以它应该在片段中。然后与 view-model 交互的片段是一种可靠的做事方式,因为这是您逻辑的主要家园。
由于 MVVM 设计模式 与众所周知的 MVC 模式相似,因为 M(模型)和 V(视图)相对相同。唯一的区别在于 C(控制器)和 VM(视图模型)之间。
- 型号
表示数据+状态+业务逻辑。它既不绑定到视图也不绑定到控制器,这使得它可以在许多上下文中重用。
- 查看
绑定到视图模型公开的可观察变量和操作。多个视图可以绑定到单个视图模型。
- 查看模型
负责包装模型并准备视图所需的可观察数据。它还为视图提供挂钩以将事件传递给模型。需要牢记的重要一点是视图模型与视图无关。
我不认为对此只有一个答案,并且会说它是自以为是的。我认为两者都有效。
您还需要考虑到体系结构组件不能与 AlertDialogs 一起“开箱即用”,因此即使您想要它的 VM,您也必须通过 fragment/activity 检索它(基本上a ViewModelProvider) 或使用其他解决方案,如 DI。 您还必须管理 AlertDialog 的生命周期以获得 ViewModel 的一些好处。
以下是可能的解决方案:
- 将 AlertDialog 视为 FragmentOne 视图的一部分,并通过回调与其通信。在实现中与 FragmentOneViewModel 通信。
- 改用 DialogFragment 和 ViewModel。由于 DialogFragment 基本上只是一个片段,您可以获得架构组件 ViewModel 的所有好处。您可以在两者之间共享 FragmentOneViewModel 或创建专用于对话框的新 ViewModel。是共享还是创建一个新的取决于您的需要,但我会考虑对话框的复杂性以及它是否应该是独立的。如果您决定共享 ViewModel,请注意您使用的是哪个 ViewModelProvider 以确保它们实际上是共享的,而不是不同的实例。
至于从 AlertDialog 返回通信,我建议使用带回调的接口,而不是直接传递 Context 和强制转换。 您可以在构造函数中接受一个实现。