【问题标题】:How to manage a DialogFragment with RxJava?如何使用 RxJava 管理 DialogFragment?
【发布时间】:2015-09-05 22:27:09
【问题描述】:

我一直在尝试确定是否可以创建一个可观察的DialogFragment。基本上我希望能够:

  • 创建并显示DialogFragment
  • 取回一个 rx Observable 可以订阅结果(确定/取消按下、字符串输入、后台任务成功/失败等)
  • 正确处理配置更改

到目前为止,我发现的最接近的东西是 ReactiveDialog,它曾经是 RxAndroid 的一部分,但作为简化 RxAndroid 的一部分,它一直是 removed from RxAndroid in v1.0.0

虽然ReactiveDialog 确实符合我的前两个标准,但它似乎无法处理配置更改。有两个问题需要考虑:

  1. DialogFragment 必须在配置更改期间保持其 Observable,以便通知订阅者其状态。
  2. 订阅者必须能够继续订阅或在配置更改后重新订阅(显然不会产生内存泄漏)。

我对 RxJava 还很陌生,所以我仍在努力思考你将如何管理这样的事情。这似乎应该是可能的,但我觉得它需要一个静态或单例 Observable 经理,可能还有 retainedInstance DialogFragments

有人对此有任何建议或最佳做法吗?

【问题讨论】:

    标签: java android android-dialogfragment rx-java


    【解决方案1】:

    这里有两个问题;一个是您不想在重新布局期间丢失 Java 对象 - 请查看 runtime changes docs

    另一个问题是,当触发该操作时,您希望创建一个具有对话框操作的 Observable。为此,请查看 RxJava 文档,Asynchronous Observer example。您需要创建一个Observable.OnSubscribe,并将该Subscriber 传递给您的代码,该代码将调用必要的onNext/onError/onCompleted 调用。

    【讨论】:

      【解决方案2】:

      我会在对话框中使用 ViewModel 来帮助更改配置。配置更改后重新订阅对话框的 ViewModel。

      1。组件

      • 屏幕(活动/片段)- 这将显示对话框片段
      • DialogFragment - 对话框。将发布有关用户操作的更新。
      • DialogViewModel - 保存用户的操作流

      2。实施

      SimpleActivity

      public class SimpleActivity extends AppCompatActivity {
      
          private SimpleDialogViewModel dialogViewModel;
          private CompositeDisposable compositeDisposable;
      
          @Override
          protected void onCreate(@Nullable Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              dialogViewModel = ViewModelProviders.of(this).get(SimpleDialogViewModel.class);
              compositeDisposable = new CompositeDisposable();
      
              showDialog();
          }
      
          @Override
          protected void onResume() {
              super.onResume();
      
              Disposable disposable =
              dialogViewModel
                      .actionStream()
                      .subscribe(
                              result -> {
      
                                  if (AlertDialog.BUTTON_POSITIVE == result) {
                                      // User clicked yes
                                  }
      
                                  if (AlertDialog.BUTTON_NEGATIVE == result) {
                                      // User clicked no
                                  }
      
                              }
                      );
              compositeDisposable.add(disposable);
          }
      
          @Override
          protected void onPause() {
              super.onPause();
      
              compositeDisposable.clear();
          }
      
          private void showDialog() {
              SimpleDialogFragment dialogFragment = new SimpleDialogFragment();
              dialogFragment.show(getSupportFragmentManager(), SimpleDialogFragment.TAG);
          }
      }
      
      

      SimpleDialogFragment

      public class SimpleDialogFragment extends DialogFragment {
      
          public static final String TAG = "SimpleDialogFragment";
      
          private SimpleDialogViewModel dialogViewModel;
      
          @Override
          public void onCreate(@Nullable Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              dialogViewModel = ViewModelProviders.of(getActivity()).get(SimpleDialogViewModel.class);
          }
      
          @Nullable
          @Override
          public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
              return inflater.inflate(R.layout.dialog_simple_message, container, false);
          }
      
          @Override
          public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
              final View btnYes = view.findViewById(R.id.yes);
              final View btnNo = view.findViewById(R.id.no);
      
              btnYes.setOnClickListener(v -> dialogViewModel.onClickYes());
              btnNo.setOnClickListener(v -> dialogViewModel.onClickNo());
          }
      }
      

      SimpleDialogViewModel

      public class SimpleDialogViewModel extends ViewModel {
      
          private Subject<Integer> actionSubject;
      
          SimpleDialogViewModel() {
              actionSubject = PublishSubject.create();
          }
      
          public void onClickYes() {
              actionSubject.onNext(AlertDialog.BUTTON_POSITIVE);
          }
      
          public void onClickNo() {
              actionSubject.onNext(AlertDialog.BUTTON_NEGATIVE);
          }
      
          public Observable<Integer> actionStream() {
              return actionSubject;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-29
        相关资源
        最近更新 更多