【Android Jetpack 全家桶全面学习】 Fragment 之间共享数据

Activity 中的两个或更多 Fragment 需要相互通信是一种很常见的情况。

想象一下主从 Fragment 的常见情况,假设有一个 Fragment,在该 Fragment 中,用户从列表中选择一项,还有另一个 Fragment,用于显示选定项的内容。

这种情况不太容易处理,因为这两个 Fragment 都需要定义某种接口描述,并且所有者 Activity 必须将两者绑定在一起。此外,这两个 Fragment 都必须处理另一个 Fragment 尚未创建或不可见的情况。

可以使用 ViewModel 对象解决这一常见的难点。这两个 Fragment 可以使用其 Activity 范围共享 ViewModel 来处理此类通信,如以下示例代码所示:

    public class SharedViewModel extends ViewModel {
        private final MutableLiveData selected = new MutableLiveData();

        public void select(Item item) {
            selected.setValue(item);
        }

        public LiveData getSelected() {
            return selected;
        }
    }

    public class MasterFragment extends Fragment {
        private SharedViewModel model;
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
            itemSelector.setOnClickListener(item -> {
                model.select(item);
            });
        }
    }

    public class DetailFragment extends Fragment {
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
            model.getSelected().observe(this, { item ->
               // Update the UI.
            });
        }
    }

请注意,这两个 Fragment 都会检索包含它们的 Activity。这样,当这两个 Fragment 各自获取 ViewModelProvider 时,它们会收到相同的 SharedViewModel 实例(其范围限定为该 Activity)。

此方法具有以下优势:

  • Activity 不需要执行任何操作,也不需要对此通信有任何了解。
  • 除了 SharedViewModel 约定之外,Fragment 不需要相互了解。如果其中一个 Fragment 消失,另一个 Fragment 将继续照常工作。
  • 每个 Fragment 都有自己的生命周期,而不受另一个 Fragment 的生命周期的影响。如果一个 Fragment 替换另一个 Fragment,界面将继续工作而没有任何问题。

ViewModelProviders 示例

注:ViewModelProviders 已 Deprecated

activity

MyAppViewModelFactory factory = MyAppViewModelFactory.getInstance(getApplication());
ViewModelProviders.of(this, factory).get(VM.class);

fragment

MyAppViewModelFactory factory = MyAppViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProviders.of(getActivity(), factory).get(VM.class);

activity 和 fragment 拿到的是同一个 vm。 这表明一个 activity 和多个 fragment 可以使用同一个 vm,由同一个 vm 来管理数据。

Fragment 相关面试题

【Android Jetpack 全家桶全面学习】 Fragment 之间共享数据_第1张图片

【Android Jetpack 全家桶全面学习】 Fragment 之间共享数据_第2张图片

Android 框架源码解析视频
Android 大厂面试题精讲视频

你可能感兴趣的