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

与其他 Fragment 通信

这节课教你
  1. 定义接口
  2. 实现接口
  3. 发送消息到一个 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();
        }
    }
}
 
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。