7 同一个activity进行通讯



尽管fragment被实现作为一个对象,是独立于activity的,可以被用于多个activity中,但是,一个fragment的实体是被直接绑定在使用它的那个activity上的。

具体来说,这个fragment能够通过getActivity()方法进入这个activity,并且很容易的进行操作,e.g.:找到activity layout中的一个view

View listView = getActivity().findViewById(R.id.list);

同样的,你的activity也能够使用FragmentManager的findFragmentById()或者findFragmentByTag()来调用fragment中的方法。

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);



7.1给activity创建事件回调


有时你希望一个fragment同activity分享一些事件,一个很好的方式就是在这个fragment中定义一个回调接口,然后需要使用这个fragment的activity实现这个接口。 当这个activity通过这个接口收到一个回调的时候,他就能够同其他在这个layout中的fragments 来分享信息了。(不同的fragment类在不同的地方,直接没有关系,只有当这些fragment类被同一个activity需要,从而实例化的时候,他们就有关系了,这个关系就是这个拥有他们实例的activity)


举个例子,如果一个新闻应用在一个activity中有两个fragments,一个展示 文档列表(fragment A),一个展示一片文章(fragment B), 当fragment A 中的一个item被选择后,要通知fragment B 来显示这个文章,在这个例子中 OnArticleSelectedListener接口就再fragment A中被声明了。

public static class FragmentA extends ListFragment {

    ...

    // Container Activity must implement this interface

    public interface OnArticleSelectedListener {

        public void onArticleSelected(Uri articleUri);

    }

    ...

}

拥有这个fragment的activity实现 OnArticleSelectedListener接口,重写onArticleSelected这个方法,然后通知fragment B 关于来自fragment A的这个事件。为了确保这个activity会实现这个接口,fragment A 的onAttach() 调用方法实例化OnArticleSelectedListener 类型的一个Activity(他是通过onAttach()传入的,也就是说现在传入的这个activity在使用这个fragment)(onAttach()方法 当这个fragment加入到某个activity时会被调用)

public static class FragmentA extends ListFragment {

    OnArticleSelectedListener mListener;

    ...

    @Override

    public void onAttach(Activity activity) {

        super.onAttach(activity);

        try {

            mListener = (OnArticleSelectedListener) activity;

        } catch (ClassCastException e) {

            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");

        }

    }

    ...

}

如果这个activity没有实现这个接口,然后这个fragment就会扔出一个ClassCastException的错误。如果实现了,mListener就是OnArticleSelectedListener这个接口的activity的实现,于是fragment A 就能够通过调用被OnArticleSelectedListener这个接口定义的方法来同activity分享事件。e.g.: 如果fragment A 继承了ListFragment,每次用户点击a list item,系统就会在fragment中调用onListItemClick(),然后这个接口的onArticleSelected()方法就会被调用来同activity分享这个事件。

public static class FragmentA extends ListFragment {

    OnArticleSelectedListener mListener;

    ...

    @Override

    public void onListItemClick(ListView l, View v, int position, long id) {

        // Append the clicked item's row ID with the content provider Uri

        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);

        // Send the event and Uri to the host activity

        mListener.onArticleSelected(noteUri);

    }

    ...

}

onListItemClick()中的id参数是这个被点击的item的row ID, 用于从这个应用的ContentProvider中获取文章。

7.2给Action Bar添加items

通过实现onCreateOptionsMenu(),你的fragments 能够给activity的Options Menu/Action Bar 贡献菜单项。 为了让这个方法能够接受调用,你必须在onCreate()中调用setHasOptionsMenu()方法,从而表示这个fragment能够给Options Menu增加items。否则,这个fragment不会接受一个到onCreateOptionsMenu()的调用。

从fragment添加到Options Menu的任何items都会被附加到已经存在的菜单项中去。当一个菜单项被选择时,这个fragment也接收到onOptionsItemSelected()方法的回调。

你也可以通过调用registerForContextMenu()方法在你的fragment layout中注册一个view来提供一个上下文菜单,当用户打开这个上下文菜单的时候,这个fragment 接受到一个onCreateContextMenu()的调用,当用户选择一个item时,这个fragment接收到一个onContextItemSelected()的调用。

尽管你的frogment给每一个增加的菜单项都接受一个on-item-selected回调,但是当用户选择一个菜单项时,这个activity首先接受各自的回调。如果这个activity关于on-item-selected回调的实现没有处理被选择的项,这个时间会被传递到fragment的回调。对选项菜单和上下文菜单,这时对的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值