与其他 Fragment 通信
这节课教你
- 定义接口
- 实现接口
- 发送消息到一个 Fragment
你还需要阅读
试试
FragmentBasics.zip
为了重用 Fragment UI 组件,你应该把每个 Fragment 构造成定义自己的布局和行为的完整的自包含的模块化的组件。一旦你定义了这些可重用的 Fragment,你可以把它们关联到一个 Activity 并使用应用逻辑连接它们实现整体的组合 UI。
通常你希望一个 Fragment 与其他 Fragment 通信,例如根据用户事件改变内容。所有的 Fragment-to-Fragment 通信都通过关联的 Activity 完成。两个 Fragment 永远都不应该直接通信。
定义接口
为了允许一个 Fragment 与它的 Activity 通信,你可以在 Fragment 类中定义一个接口并在 Activity 中实现它。Fragment 在它的 onAttach() 生命周期方法中捕获接口实现,然后能调用接口的方法与 Activity 通信。
这里是一个 Fragment 到 Activity 通信的例子:
public class HeadlinesFragment extends ListFragment { OnHeadlineSelectedListener mCallback; // 容器 Activity 必须实现这个接口 public interface OnHeadlineSelectedListener { public void onArticleSelected(int position); } @Override public void onAttach(Activity activity) { super.onAttach(activity); // 确保容器 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) { // 发送事件给宿主 activity mCallback.onArticleSelected(position); }
实现接口
为了接收 fragment 的事件回调,宿主 activity 必须实现这个 fragment 类中定义的接口。
例如,下面的 activity 实现了上面例子中的接口。
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // 用户在 HeadlinesFragment 中选中了文章标题 // 在这里做些事情显示那篇文章 } }
发送消息到一个 Fragment
宿主 activity 使用
findFragmentById()
捕获Fragment
的实例,然后直接调用 fragment 的公有方法发送消息。
例如,想象下前面的 activity 可能包含另一个 fragment 用于显示上面的回调方法中返回的数据指定的项。在这种情况下,activity 可以把回调方法中收到的信息传给其他显示这个项的 fragment:
public static class MainActivity extends Activity implements HeadlinesFragment.OnHeadlineSelectedListener{ ... public void onArticleSelected(int position) { // 用户在 HeadlinesFragment 中选中了文章标题 // 在这里做些事情显示那篇文章 ArticleFragment articleFrag = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment); if (articleFrag != null) { // 如果文章 fragment 可用,我们使用的是两栏布局... // 调用 ArticleFragment 的方法更新它的内容 articleFrag.updateArticleView(position); } else { // 否则,我们使用的是单栏布局,必须切换 fragment... // 创建 fragment 并给它一个选中的文章的参数 ArticleFragment newFragment = new ArticleFragment(); Bundle args = new Bundle(); args.putInt(ArticleFragment.ARG_POSITION, position); newFragment.setArguments(args); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // 用这个 fragment 替换 fragment_container 视图中东西 // 并把事务添加到返回栈,让用户可以导航回来 transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // 提交事务 transaction.commit(); } } }
时间: 2024-10-11 16:41:06