所有片段到片段的通信都是通过共享的ViewModel或相关联的Activity完成的。两个片段不应直接通信。
片段之间通信的不同方式:
The recommended way to communicate between fragments is to create a shared ViewModel object. Both fragments can access the ViewModel through their containing Activity. The Fragments can update data within the ViewModel and if the data is exposed using LiveData the new state will be pushed to the other fragment as long as it is observing the LiveData from the ViewModel. To see how to implement this kind of communication, read the 'Share data between Fragments' section in the ViewModel guide.
You can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.
public class HeadlinesFragment extends ListFragment {
OnHeadlineSelectedListener mCallback;
public interface OnHeadlineSelectedListener {
public void onArticleSelected(int position);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnHeadlineSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
...
}
现在,Fragment可以通过使用OnHeadlineSelectedListener接口的mCallback实例调用onArticleSelected()方法(或其他方法)向Activity发送消息。
例如,在用户单击列表项时,以下方法将在Fragment中被调用。 Fragment使用回调接口将事件传递给父Activity。
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
mCallback.onArticleSelected(position);
}
实现接口
为了从片段中接收事件回调,托管该片段的活动必须实现片段类中定义的接口。
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
}
}
向片段传递消息
主活动可以通过使用findFragmentById()捕获片段实例并直接调用片段的公共方法,向片段传递消息。
例如,假设上面展示的活动可能包含另一个用于显示由上述回调方法返回的数据中指定的项的片段。在这种情况下,活动可以将接收到的信息传递给另一个将显示该项的片段:
public static class MainActivity extends Activity
implements HeadlinesFragment.OnHeadlineSelectedListener{
...
public void onArticleSelected(int position) {
ArticleFragment articleFrag = (ArticleFragment)
getSupportFragmentManager().findFragmentById(R.id.article_fragment);
if (articleFrag != null) {
articleFrag.updateArticleView(position);
} else {
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
来自官方文档。存档版本