关于Fragment与Fragment、Activity通信的四种方式

举报
江南一点雨 发表于 2021/08/17 00:23:46 2021/08/17
【摘要】 一直想总结一下Fragment与Fragment、Activity通信的问题,今天有时间一共总结了三种,权当抛砖引玉,如果大家还有更好的方式来实现Fragment和Fragment、Activity的通信,欢迎提出来,我们一起学习。好了,我们先来看看今天要实现的一个效果图: 左边是一个Fragment,右边是一个Fragment,当我们点击左边的Fragment的时候,右...

一直想总结一下Fragment与Fragment、Activity通信的问题,今天有时间一共总结了三种,权当抛砖引玉,如果大家还有更好的方式来实现Fragment和Fragment、Activity的通信,欢迎提出来,我们一起学习。好了,我们先来看看今天要实现的一个效果图:



左边是一个Fragment,右边是一个Fragment,当我们点击左边的Fragment的时候,右边的Fragment中显示出我们所点击的人的作品,我们就来看看怎样实现两个Fragment之间的通信。


1.直接在一个Fragment中调用另外一个Fragment中的方法

我们可以直接在一个Fragment中调用另外一个Fragment的公开方法,前提是要先拿到另外一个Fragment的实例,我们先来看看怎样在左边的Fragment中拿到右边Fragment的实例:


  
  1. ContentFragment cf = (ContentFragment) getActivity()
  2. .getFragmentManager().findFragmentById(
  3. R.id.content_fg);
  4. cf.showPro(name);


  
  1. public void showPro(String key) {
  2. list = map.get(key);
  3. adapter = new ArrayAdapter<String>(getActivity(),
  4. android.R.layout.simple_list_item_1, list);
  5. lv.setAdapter(adapter);
  6. }
先根据传进来的人名拿到该人作品的数据集,然后构造一个adapter赋值给listview,很简单吧。使用这种方式我们可以直接在一个Fragment中调用另一个Fragment的公开方法,从而实现两个Fragment的通信。

这种方法适于那些我们在布局文件中就已经定义了的Fragment,这种Fragment每个都有id,可以通过FragmentManager找到,但是如果我们使用了ViewPager,即每个Fragment都是动态添加进来的,这个时候我们无法通过FragmentManager获得另外一个Fragment的实例,那么该怎么办呢?这时我们就要用到下面这种方式了。

2.使用接口

接口可以实现两个Fragment之间的通信,也可以实现Fragment和Activity之间的通信,这大概是用的比较多的一种方式,也是个人比较推荐的一种方式,使用接口来实现两个Fragment之间通信,要通过宿主Activity中转一下,如果是Fragment和宿主Activity通信则直接调用即可,我们先看看上图中点击韩愈的时候怎么出现他的作品。首先在左边的Fragment中定义一个接口:

   
  1. public interface showPro {
  2. public void showProByName(String name);
  3. }

然后定义一个接口变量:
private showPro mCallback;
  

我们要在宿主Activity中实现这个接口,这样当Fragment调用onAttach方法时我们就可以实例化这个接口了:


   
  1. @Override
  2. public void onAttach(Activity activity) {
  3. super.onAttach(activity);
  4. if (activity != null) {
  5. mCallback = (showPro) activity;
  6. }
  7. }
当mCallback实例化之后,那么我们在点击韩愈的时候就可以调用这里边的showProByName方法了:


   
  1. lv.setOnItemClickListener(new OnItemClickListener() {
  2. @Override
  3. public void onItemClick(AdapterView<?> parent, View view,
  4. int position, long id) {
  5. TextView nameTV = (TextView) view;
  6. String name = nameTV.getText().toString();
  7. if ("韩愈".equals(name)) {
  8. mCallback.showProByName(name);
  9. }
  10. }
  11. });

当然,这个方法的具体实现在宿主Activity中,当宿主Activity实现了showPro接口之后,接着就要实现它里边的方法了:

   
  1. public class MainActivity extends Activity implements showPro {
  2. private ContentFragment cf;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. getActionBar().hide();
  8. cf = (ContentFragment) getFragmentManager().findFragmentById(
  9. R.id.content_fg);
  10. }
  11. @Override
  12. public void showProByName(String name) {
  13. cf.showPro(name);
  14. }
  15. }

我们在接口的方法中调用右边Fragment中的showPro方法,并将当前人名作为参数传入,这个方法与1中相同,我就不贴代码了。这个方法与1中介绍的方法相比,虽然有点麻烦,但是可以有效的解决在一个Fragment中拿不到另一个Fragment实例的问题,具体应用场景就是ViewPager中的Fragment之间通信。

3.使用广播

不论我们有没有用ViewPager,都可以用广播实现两个Fragment之间的通信,广播算是这里最灵活的通信方式了,我们看看在左边Fragment中发送广播:

   
  1. Intent intent = new Intent("showPro");
  2. intent.putExtra("name", name);
  3. LocalBroadcastManager.getInstance(getActivity())
  4. .sendBroadcast(intent);

在右边Fragment中接收广播:

   
  1. LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
  2. .getInstance(getActivity());
  3. IntentFilter intentFilter = new IntentFilter();
  4. intentFilter.addAction("showPro");
  5. BroadcastReceiver br = new BroadcastReceiver() {
  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. String key = intent.getStringExtra("name");
  9. list = map.get(key);
  10. adapter = new ArrayAdapter<String>(getActivity(),
  11. android.R.layout.simple_list_item_1, list);
  12. lv.setAdapter(adapter);
  13. }
  14. };
  15. localBroadcastManager.registerReceiver(br, intentFilter);

这些都是广播基本的使用方法,我就不啰嗦了。

个人觉得,虽然广播用起来最方便,但是在选择使用哪种通信方式的时候,优先选择上面两种,如果前两种方式都不可以,再考虑使用广播。

续:

之前还忽略了一种,这里补充一下。

4.Fragment直接调用Activity中的public方法

我们也可以直接在Fragment中调用Activity中的公开方法,如下:
((MainActivity) getActivity()).showProByName(name);
  
这里的showProByName就是我们上文贴出来的那个MainActivity中的方法。

如果大家还有更好的实现两个Fragment通信的方式,欢迎提出来,一起学习。



文章来源: wangsong.blog.csdn.net,作者:_江南一点雨,版权归原作者所有,如需转载,请联系作者。

原文链接:wangsong.blog.csdn.net/article/details/49786417

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。