首页 > 解决方案 > MVVM - How to cleanly incorporate AlertDialog?

问题描述

I have a FragmentOne which contains the MVVM pattern. The Fragment has it's own ViewModel, FragmentOneViewModel. I am unsure on how to cleanly incorporate an AlertDialog in my case.

In the Fragment it contains a RecyclerViewAdapter, with each row that contains a Button to create an AlertDialog. Do I need a ViewModel for the AlertDialog?

Or can I use an interface callback and implement it on my Fragment, which will be called when the user clicks on buttons in the AlertDialog. And then use that input to call the Fragment's 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);
    }

}

And then calling the viewmodel from the callback method:

//Fragment class:

public class MembersFragment extends Fragment implements ActivateUserDialog.DialogOnClickListener

@Override
    public void onConfirmBtnClick(String amount){
        mViewModel.activateUser(amount);
    }

Is this a clean way to do it?

标签: androidandroid-mvvm

解决方案


我不认为它有一个单一的答案,并且会说它是固执己见的。在我看来,两者都是有效的。

您还需要考虑架构组件不能“开箱即用”与 AlertDialogs 一起工作,因此即使您想要一个 VM,您也必须通过片段/活动(基本上是ViewModelProvider)检索它或使用其他一些DI 之类的解决方案。您还必须管理 AlertDialog 的生命周期才能获得 ViewModel 的一些好处。

以下是可能的解决方案:

  1. 将 AlertDialog 视为 FragmentOne 视图的一部分,并通过回调与其通信。在实现中与 FragmentOneViewModel 进行通信。
  2. 改为使用带有 ViewModel的DialogFragment 。由于 DialogFragment 基本上只是一个 Fragment,因此您可以获得架构组件 ViewModel 的所有好处。您可以在两者之间共享 FragmentOneViewModel,也可以创建专用于对话框的新 ViewModel。是否共享或创建一个新的取决于您的需要,但我会考虑对话框的复杂性以及它是否应该是独立的。如果您决定共享 ViewModel,请注意您使用的ViewModelProvider以确保它们实际上是共享的,而不是不同的实例。

至于从 AlertDialog 回传,我建议使用带有回调的接口,而不是直接传递 Context 和强制转换。您可以在构造函数中接受实现。


推荐阅读