在关Fragment间参数的传递,有两种情况:

  • 第一种情况:同一个container中不同fragment间的参数传递。这种情况一般发生在fragment跳转时,上一个Fragment将参数传递给下一个Fragment。
  • 第二种情况:是同一个Activity中,不个container间Fragment的参数传递。

有关第一种情况,以前写过一篇文章,详细说明了上一个Fragment将参数传递给下一个Fragment,及数据回传的方法。详细参见: 《Fragment跳转时传递参数及结果回传的方法》

下面详细看看这两种参数传递方法。

一、同一个container间的参数传递。

有关这个问题,请大家移步以前写的一篇文章:《Fragment跳转时传递参数及结果回传的方法》,在这篇文章中有关Fragment跳转时的参数传递和结果回传已经讲的很清楚了,这里就没必要重新再写一遍,下面是这篇文章的效果图:

  • 1、在界面开始时,点击“加载第二个Fragment”按钮
  • 2、调起Fragment2,并向其传递一个参数“从Fragment1传来的参数”,显示在Fragment2中
  • 3、点击Fragment2中的四个小动物中的一个,会向Fragment1回传用户点击的是哪个动物,在Fragment1中显示出来。

看起来挺有意思?那就移步到这篇文章里看看吧

二、同一个Activity,不同container间的参数传递

这里到了这篇文章的重点内容了哦,这可并不是说上一部分不重要哈,其实上一部分要比这部分重要!同一个container中不同Fragment间的参数传递一般的工程都会用到的,所以大家一定要看。而我这里不讲,是因为以前有讲过,这里就没必要再重复一遍了,好了,废话说了好多……开整吧。
先看看效果图:
1、在这个Actiivty中有两个Fragment;
2、Fragment1中有一个listView,当我们点击ListView的Item的时候,把Item上的内容更新到Fragment2上

这里有多种实现方法,最可取的是方法三。我们由简到易慢慢讲。
我们想使两个fragment实例要能通信,那如果我们都能通过findViewById()找到所有的控件,直接操控的话,岂不就实现了。而通过findViewById()能找到所有控件实例的地方就是在Activity中了,所以这就有了方法一。

方法一:直接在Activity中操作

在Activity中找到对应的控件实例,然后直接操控即可。
先看看MainActivity的布局:activity_main.xml

[html]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/main_layout"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="horizontal"
  6. android:baselineAligned="false" >
  7. <fragment
  8. android:id="@+id/fragment1"
  9. android:name="com.harvic.com.harvicblog5_1.Fragment1"
  10. android:layout_width="0dip"
  11. android:layout_height="match_parent"
  12. android:layout_weight="1" />
  13. <fragment
  14. android:id="@+id/fragment2"
  15. android:name="com.harvic.com.harvicblog5_1.Fragment2"
  16. android:layout_width="0dip"
  17. android:layout_height="match_parent"
  18. android:layout_weight="1" />
  19. </LinearLayout>

在这个布局中,横向放两个fragment,由于这里的fragment是静态添加的,所以每个fragment都是有id值的,所以这时候如果我们要获取某个fragment的实例,就可以通过FragmentManager::findFragmentById()来找到了。
然后是这两个fragment的布局。
fragment1.xml:

[html]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:background="#ff00ff"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:text="This is fragment 1"
  10. android:textColor="#000000"
  11. android:textSize="25sp" />
  12. <ListView
  13. android:id="@+id/list"
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"></ListView>
  16. </LinearLayout>

可以看到fragment1的布局中,除了一个标识当前Fragment的TextView,就是一个listview;
fragment2.xml:

[html]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:background="#ffff00"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:id="@+id/fragment2_tv"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:text="This is fragment 2"
  11. android:textColor="#000000"
  12. android:textSize="25sp" />
  13. </LinearLayout>

可以看到在fragment2中非常干净,只有一个TextView来显示当前用户在fragment1中的点击结果。
下面看看在MainActivity中是如何实现的吧

[java]  view plain copy
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mStrings);
  5. ListView listView = (ListView)findViewById(R.id.list);
  6. listView.setAdapter(arrayAdapter);
  7. mFragment2_tv = (TextView)findViewById(R.id.fragment2_tv);
  8. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  9. @Override
  10. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  11. mFragment2_tv.setText(mStrings[position]);
  12. }
  13. });
  14. }

其中:

[java]  view plain copy
  1. private String[] mStrings = {"Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
  2. "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
  3. "Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
  4. "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
  5. "Allgauer Emmentaler"};

难度不大,通过(ListView)findViewById(R.id.list);找到fragment1中的listview,通过(TextView)findViewById(R.id.fragment2_tv);找到fragment2中的textView,然后直接对他们进行操作。即下面的代码:

[java]  view plain copy
  1. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  2. @Override
  3. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  4. mFragment2_tv.setText(mStrings[position]);
  5. }
  6. });

当用户点击listView的一个item时,将值setText到fragment2的textView中。

源码在文章底部给出

可见,直接在activity中操作各个fragment的控件就可以实现消息互传。但,这样真的好吗?如果每个fragment中的控件都在Activity中操作,那还要fragment干嘛!最最起码,应该每个fragment负责自己的控件操作才对嘛!
所以,我们对这种方法进行改进,将点击Item的赋值操作放到fragment1中去。所以,这就有方法二;

方法二:直接在fragment中操作

在这里我们会把所有方法写在Fragment1中,这里涉及到两方面的内容:
第一:在Fragment中如何获得自己控件的引用,比较这里Fragment1里的listview控件。
第二:在Fragment中如何获得其它Fragment页面中控件的引用,比如这里Fragment2里的TextView控件。 
首先,获取自己控件引用的方法: 
方法一:在onCreateView()中获取。 
就比如这里获取自己的listView控件的引用,代码如下:

[java]  view plain copy
  1. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  2. Bundle savedInstanceState) {
  3. View rootView = inflater.inflate(R.layout.fragment1, container, false);
  4. listView = (ListView)rootView.findViewById(R.id.list);//获取自己视图里的控件引用,方法一
  5. return rootView;
  6. }

由于在onCreateView()中,还没有创建视图,所以在这里如果使用getView()方法将返回空。所以如果要获取其实图中指定控件的引用,只用用inflater.inflate()返回的rootView;在这个rootView()中用findViewById来查找。
方法二:在onActivityCreated()函数中获取。
从 《Fragment详解之一——概述》 的流程图中可以看到,onActivityCreated()回调会在Activity的OnCreate()执行完成后再执行,也就是说,onActivityCreated()会在Activity的OnCreate()工作完成以后才会执行。所以当执行到onActivityCreated()的时候Activity已经创建完成,它其中的各个fragment也视图等等的也都已经创建完成。所在可以在这里获取跟Activity相关的各种资源。第二个问题中的获取其它Fragment页面中控件的引用也是在onActivityCreated()中来做的。先看看在onActivityCreated()中如何获得自己视图中控件的引用吧

[java]  view plain copy
  1. public void onActivityCreated(Bundle savedInstanceState) {
  2. super.onActivityCreated(savedInstanceState);
  3. listView = (ListView) getView().findViewById(R.id.list);//获取自己视图里的控件引用,方法二
  4. }

然后,获得其它Fragment页面中控件的引用的方法
在上面已经说了,要获取Activity中的资源,就必须等Acitivity创建完成以后,所以必须放在onActivityCreated()回调函数中。
其获取方法为:

[java]  view plain copy
  1. public void onActivityCreated(Bundle savedInstanceState) {
  2. super.onActivityCreated(savedInstanceState);
  3. mFragment2_tv = (TextView) getActivity().findViewById(R.id.fragment2_tv);//获取其它fragment中的控件引用的唯一方法!!!
  4. }

上面讲了一堆之后,下面就看看在Fragment1中如何实现的吧。
由上面的讲述可知,无论是获取自己视图中控件的引用还是获取其它fragment中控件的引用都可以放在onActivityCreated()函数中,所以我们就把它们全部放在onActivityCreated()中来实现了。

[java]  view plain copy
  1. public void onActivityCreated(Bundle savedInstanceState) {
  2. super.onActivityCreated(savedInstanceState);
  3. mFragment2_tv = (TextView) getActivity().findViewById(R.id.fragment2_tv);//获取其它fragment中的控件引用的唯一方法!!!
  4. listView = (ListView) getView().findViewById(R.id.list);//获取自己视图里的控件引用,方法二
  5. ArrayAdapter arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mStrings);
  6. listView.setAdapter(arrayAdapter);
  7. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  8. @Override
  9. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  10. String str = mStrings[position];
  11. mFragment2_tv.setText(str);
  12. }
  13. });
  14. }

难度不大,也是获取到了每个控件以后,直接对他们进行操作。

源码在文章底部给出

我们这里直接在fragment1中操作了fragment2的控件,这样就违背了模块分离的思想,我们应该让他们各自处理各自的代码才好。所以,考虑到将他们分离,我们这里就出现了方法三。

方法三:在各自的fragment中操作

好,我们先想想要怎么解决这个问题,首先,我们把各自的事件放在各自的fragment中处理,即在fragment1中能得到当前用户点击的ITEM的String字符串,在fragment2中可以设置textview的值。那问题来了,各自获得了各自的东东,那通过什么让他们交互呢?
答案显然是activity。
很显然,在activity中可以直接通过FragmentManager::findFragmentById()来获取fragment2的实例。进而调用fragment2中的任意方法,这就实现了与fragment2的通信。
那fragment1又怎么把结果回传给Activity呢?大家如果在看到这里之前先看了《Fragment跳转时传递参数及结果回传的方法》就很容易想到,用回调!请记住。在不同页面中回传结果,回调是万能的解决方案。
1、Fragment2设置textView函数:
先看个简单的,fragment2中的处理代码:

[java]  view plain copy
  1. public class Fragment2 extends Fragment {
  2. private TextView mTv;
  3. …………
  4. public void setText(String text) {
  5. mTv.setText(text);
  6. }
  7. }

2、Fragment1中的处理方式:
(1)、定义接口及变量
由于是用回调,所以要先定义一个接口及对应的变量:

[java]  view plain copy
  1. private titleSelectInterface mSelectInterface;
  2. public interface titleSelectInterface{
  3. public void onTitleSelect(String title);
  4. }

(2)、接口变量赋值
接口是给activity用的,所以要在activity中给这里的接口变量赋值,可以有很多方法,当然可以选择写一个setXXX()函数来赋值,但如果用户忘了怎么办?所以我们要强制用户赋值。所以采用强转的方式,在fragment与activity相关联时,进行强转赋值:

[java]  view plain copy
  1. public void onAttach(Activity activity) {
  2. super.onAttach(activity);
  3. try {
  4. mSelectInterface = (titleSelectInterface) activity;
  5. } catch (Exception e) {
  6. throw new ClassCastException(activity.toString() + "must implement OnArticleSelectedListener");
  7. }
  8. }

采用强转的方式的问题在于,如果用户的activity没有implements titleSelectInterface,就会抛出错误,所以在调试过程中就会发现。
(3)、调用接口变量
下一步就是在fragment1中在用户点击listView的item的时候,将结果回传给Activity了,代码如下:

[java]  view plain copy
  1. public void onActivityCreated(Bundle savedInstanceState) {
  2. super.onActivityCreated(savedInstanceState);
  3. listView = (ListView) getView().findViewById(R.id.list);//获取自己视图里的控件引用,方法二
  4. ArrayAdapter arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mStrings);
  5. listView.setAdapter(arrayAdapter);
  6. listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  7. @Override
  8. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  9. String str = mStrings[position];
  10. mSelectInterface.onTitleSelect(str);
  11. }
  12. });
  13. }

(4)、在Activity中实现titleSelectInterface接口
首先是MainActivity必须实现titleSelectInterface接口,然后结果会在onTitleSelect(String title)中返回,在结果返回后利用fragment2.setText()操作textView;代码如下:

[java]  view plain copy
  1. public class MainActivity extends FragmentActivity implements Fragment1.titleSelectInterface {
  2. ……
  3. @Override
  4. public void onTitleSelect(String title) {
  5. FragmentManager manager = getSupportFragmentManager();
  6. Fragment2 fragment2 = (Fragment2)manager.findFragmentById(R.id.fragment2);
  7. fragment2.setText(title);
  8. }
  9. }

在上面代码中可以看出,在结果返回后,通过findFragmentById()来获得fragment2的实例,这里首次出现了findFragmentById()函数的用法,这个函数主要用来静态添加的fragment中,通过fragment的ID值来获取它的实例。在获得fragment2的实例以后,通过调用我们写好了setText()方法来将结果显示在textView中。

[java]  view plain copy
  1. Fragment2 fragment2 = (Fragment2)manager.findFragmentById(R.id.fragment2);

Fragment ——第四步 传值相关推荐

  1. 如何优雅的实现 Activity、Fragment 相互之间的 Bundle 传值

    1.简介 从事过 Android 开发的同学,肯定遇到过 Activity 与 Activity 间的 Bundle 传值,或者 Activity 与 Fragmnet 中的 Bundle 传值,或者 ...

  2. 云信小课堂丨简单四步,快速搭建协同办公系统!

    Vol. 8 企业作为社会分工参与的主体,在自身发展以及内部协作中,势必会涉及到各类自有技术和商业信息的互动与交流,而这类信息由于有着高度的保密性和隐私性,所以如微信.QQ 等通用的即时通讯工具很难满 ...

  3. android glide加载不出图片_Glide实现共享元素无缝转场效果,只需四步!

    原文: How to Use Shared Element Transition with Glide in 4 steps 作者:Bartłomiej Osmałek 读完这篇文章, 你就会知道使用 ...

  4. android 转场动画 共享元素,关于android:四步通过Glide实现共享元素无缝转场效果...

    读完这篇文章, 你就会晓得应用Glide等图片加载库实现共享元素转场成果,以及如何解决各种可能加载状态.通过共享转场动画,能够晋升利用交互体验,让用户应用起来更愉悦. 共享元素转场成果是Materia ...

  5. ​简单四步,快速判断真菌是否成功侵染宿主植物

    撰文  |  同同 涉及植物研究的小伙伴们应该对于真菌植物共生都有所了解,根瘤菌和大豆的共生就是教科书级别的经典案例.植物与真菌的共生作为农业生产中一种重要的共生关系,一直是农业科研工作者的研究热点. ...

  6. 大佬教你修改pycharm编辑器 简单的四步教你搞定界面风格修改

    教你配置属于自己的PYcharm界面色彩风格,PYthon学习必备 GO 第一步,换成深色背景,保护视力 PyCharm默认的背景是白色的,比较刺眼.还是换成深色的比较好,而且感觉比较酷一点. 修改方 ...

  7. 在深谈TCP/IP三步握手四步挥手原理及衍生问题—长文解剖IP

    如果对网络工程基础不牢,建议通读<细说OSI七层协议模型及OSI参考模型中的数据封装过程?> 下面就是TCP/IP(Transmission Control Protoco/Interne ...

  8. excel筛选排序从小到大_数据横向排序和筛选,Ctrl+F搭配通配符quot;*quot;,只需简单四步完成...

    数据的排序和筛选,相信大家都有操作过.但我们在利用Excel表格进行数据排序筛选的时候,基本都是数据的纵向操作,也就是按列的方式进行数据操作.今天我们就来学习一下,如何对数据进行横向的排序和筛选. 如 ...

  9. java web每天定时执行任务(四步轻松搞定)

    第一步: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ...

最新文章

  1. 电芯容量在前期循环中容量增加_如何设计提高电池电芯的容量密度?
  2. 求助!妹子一个rm -rf把公司服务器数据删没了,我该怎么办?
  3. windows操作系统中配置java环境
  4. C++检查图是否为二部图的算法(附完整源码)
  5. 查看目标主机安装的杀毒软件
  6. dataframe第二列 r语言_123.R简介和统计绘图
  7. 中国送餐行业市场供需与战略研究报告
  8. phpstorm,webstorm取消自动保存并标识修改的文件为星星标记
  9. 这是一台家庭计算机重启无效,我买了一台二手计算机,配置还可以,但有时会自动重启机器,这是为什? 爱问知识人...
  10. QA:阿里云K8s启动容器后无法访问网络
  11. 单片机/嵌入式体系介绍
  12. 油溶性CdSeTe/ZnS量子点(以CdSeTe为核心,ZnS为壳层)
  13. 数据库问题——合并表格
  14. 【JavaScript问题】JavaScript 请求后台报错 Invalid character found in the request target
  15. 厦门情侣必去浪漫的餐厅
  16. 清空数据库所有表中的数据
  17. [转载] 中美德突发事件应急指挥组织结构初探
  18. 百度地图清除指定覆盖物(Overlay),保留某种覆盖物( disableMassClea),清除保留的覆盖物(enableMassClear)
  19. Ubuntu安装搜狗fcitx无法正常安装的问题
  20. 会声会影2023最新中文旗舰版新功能介绍

热门文章

  1. 小米AI实验室六篇论文获 ICASSP 2022收录,多模态语音唤醒挑战赛夺冠
  2. J2ME是闯进电信丛林的兔子?
  3. 创建型设计模式学习笔记
  4. Ensemble几种方式原理
  5. 第1章 部署虚拟环境安装linux系统
  6. 2020 5 20,100天纪念日,用C语言打印3D动态立体爱心!!!
  7. [Java并发编程-6] Callable接口
  8. JS实现图片无缝滚动效果
  9. cut最后几位 shell_linux的cut命令用法总结
  10. Excel如何每隔几行对数据进行求和