Fragment与Activity的通讯

来源:互联网 发布:软件测试好吗 编辑:程序博客网 时间:2024/05/02 06:13

在使用fragment的时候,通常的用法都是使用一个activity来管理不同的fragment,所以每个fragment与activity的及时通讯就很重要。

1、Fragment可以调用getActivity()方法很容易的得到它所在的activity的对象,然后就可以查找activity中的控件们(findViewById())。例如:

Viewlist View =getActivity().findViewById(R.id.list);
同样的,activity也可以通过FragmentManager的方法查找它所包含的frament们。例如:
ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment)

但是这个并不是最好的办法,根据fragmen的定义,我们可以在fragment里面定义一个回调接口,在activity中实现它。举个谷歌官方给的例子,这是一个新闻程序的例子,它有一个activity,activity中含有两个fragment。fragmentA显示新闻标题,fragmentB显示标题对应的内容。fragmentA必须在用户选择了某个标题时告诉activity,然后activity再告诉fragmentB,fragmentB就显示出对应的内容(为什么这么麻烦?直接fragmentA告诉fragmentB不就行了?也可以啊,但是你的fragment就减少了可重用的能力。现在我只需把我的事件告诉宿主,由宿主决定如何处置,这样是不是重用性更好呢?)。如下例:

public class PersionListFragment extends ListFragment {    private static final String STATE_ACTIVATED_POSITION = "activated_position";    private Callbacks mCallbacks = sDummyCallbacks;    private int mActivatedPosition = ListView.INVALID_POSITION;    public interface Callbacks {        public void onItemSelected(String id);    }    private static Callbacks sDummyCallbacks = new Callbacks() {        @Override        public void onItemSelected(String id) {        }    };
我们在PersionListFragment中定义了mCallbacks这个接口,当然了我们自己实现了一个空的接口内容sDummyCallbacks,当作mCallbacks的默认接口。
下面就是我们要到Activity中去实现这个接口:
public class PersionListActivity extends FragmentActivity implements PersionListFragment.Callbacks {private boolean mTwoPane;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_persion_twopane);if (findViewById(R.id.persion_detail_container) != null) {mTwoPane = true;((PersionListFragment) getSupportFragmentManager().findFragmentById(R.id.persion_list)).setActivateOnItemClick(false);}}@Overridepublic void onItemSelected(String id) {if (mTwoPane) {Bundle arguments = new Bundle();arguments.putString(PersionDetailFragment.ARG_ITEM_ID, id);PersionDetailFragment fragment = new PersionDetailFragment();fragment.setArguments(arguments);getSupportFragmentManager().beginTransaction().replace(R.id.persion_detail_container, fragment).commit();} else {Intent detailIntent = new Intent(this, PersionDetailActivity.class);detailIntent.putExtra(PersionDetailFragment.ARG_ITEM_ID, id);startActivity(detailIntent);}}}
那么实现完了接口怎么传给刚才的fragment呢?
当fragment添加到activity中时,会调用fragment的方法onAttach(),这个方法中适合检查activity是否实现了OnArticleSelectedListener接口,检查方法就是对传入的activity的实例进行类型转换,然后赋值给我们在fragment中定义的接口。
 @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        if (!(activity instanceof Callbacks)) {            throw new IllegalStateException("Activity must implement fragment's callbacks.");        }        mCallbacks = (Callbacks) activity;    }    @Override    public void onDetach() {        super.onDetach();        mCallbacks = sDummyCallbacks;    }    @Override    public void onListItemClick(ListView listView, View view, int position, long id) {        super.onListItemClick(listView, view, position, id);        mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);    }
在一个fragment从activity中剥离的时候,就会调用onDetach方法,这个时候正好可以把它的接口恢复为默认接口。防止不必要的错误。注意看onAttach方法中的代码,在赋值之前要做一个判断,看看Activity中有没有实现了这个接口,用到了instanceof。如果没有实现接口,我们就抛出异常。

这个时候我们就实现了Fragment与Activity之间的通讯,把主要的事情还是都交给管理员Activity做比较好。
代码下载在评论上
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 20个月宝宝吐了怎么办 十个月的宝宝消化不好怎么办 两岁宝宝不爱喝水怎么办 两岁宝宝不爱喝水吃饭怎么办 两岁的宝宝不爱喝水怎么办 宝宝不爱吃饭不爱喝水怎么办 一多半宝宝爱喝水 不爱吃饭怎么办 1岁宝宝不爱吃饭喝水怎么办 两岁小宝宝不爱吃饭怎么办 4个月小宝宝咳嗽怎么办 3个月小宝宝咳嗽怎么办 2个月小宝宝咳嗽怎么办 8的岁儿童腿不直怎么办 作业盒子选错年级怎么办 两岁x型腿怎么办 绿萝叶子有水滴怎么办 打游戏变菜了怎么办 车被记号笔画了怎么办 水溶性彩铅受潮了怎么办 马克笔颜色涂深了怎么办 染发膏染眉毛了怎么办 用电容笔画画手有触感怎么办 CAD画图线性数字不居中怎么办 3d立体画笔堵塞怎么办 龋齿树脂填充老化后怎么办 小孩补过的牙疼怎么办 颜料弄到墙纸上怎么办 4岁的宝宝不爱涂色怎么办 oppo手机截图存不到相册怎么办 做的ih5保存不了怎么办 小偷偷东西发现后逃跑了怎么办? 网上有人传迷信诅咒怎么办 颜料粘在衣服上怎么办 家里有小偷撬锁怎么办 在家有人在撬门怎么办 6个月的宝宝腹泻怎么办 六个月大的宝宝拉肚子怎么办 六个月宝宝着凉拉肚子怎么办 六个月婴儿着凉拉肚子怎么办 怀孕六个月着凉拉肚子怎么办 六个月的婴儿消化不好怎么办