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

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

这种状况不太容易解决,因为这两个 Fragment 都须要定义某种接口形容,并且所有者 Activity 必须将两者绑定在一起。此外,这两个 Fragment 都必须解决另一个 Fragment 尚未创立或不可见的状况。

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

    public class SharedViewModel extends ViewModel {        private final MutableLiveData<Item> selected = new MutableLiveData<Item>();        public void select(Item item) {            selected.setValue(item);        }        public LiveData<Item> 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 框架源码解析视频】
【Android 大厂面试题精讲视频】