首页 > 代码库 > 安卓训练-开始-使用 Fragment 构造动态 UI-与其他 Fragment 通信

安卓训练-开始-使用 Fragment 构造动态 UI-与其他 Fragment 通信

与其他 Fragment 通信

上一课
下一课
这节课教你
  1. 定义接口
  2. 实现接口
  3. 发送消息到一个 Fragment
你还需要阅读
  • Fragments
试试
下载示例

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();
        }
    }
}
上一课下一课
 
 

安卓训练-开始-使用 Fragment 构造动态 UI-与其他 Fragment 通信