虽然网上有很多关于Fragment的文章,但我这里还是要写这篇笔记,因为我在编写程序的过程中发现了一个问题,至今未解决,希望得到大家的帮助;
  PS:当我在Fragment中定义一个名为setIndex(int index)的方法之后,运行程序,就会报错(打印的错误信息显示错误为找不到这个Fragment对应的类),但当把这个方法的名称改为其它的名称之后,程序即可正常运行,我的api level为17和18;

先看看Fragment的生命周期方法,其实和Activity基本还是相似的,了解Activity的生命周期,再看Fragment的生命周期方法,也就比较容易理解;

先介绍相关概念

一、fragment通常作为宿主activity UI的一部分, 被作为activity整个view hierarchy的一部分被嵌入,相当于一个轻量级的Activity;

(一)、将一个fragment添加到layout,有两种方法。
1、在Layout文件中,添加一个Fragement对应的节点

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="vertical" ><fragmentandroid:id="@+id/main_mf"android:name="com.dbo4.domain.MyFragement"android:layout_width="match_parent"android:layout_height="match_parent" />
</LinearLayout>

<fragment> 中的 android:name 属性指定了在layout中具体的Fragment类. 当系统创建这个layout时, 它实例化每一个在layout中指定的fragment,并调用每一个fragment的onCreateView()方法,来获取每一个fragment的layout. 系统将从fragment返回的View直接插入到<fragment>元素所在的地方. 
需要注意的是,每一个fragment都需要一个唯一的标识, 如果activity重启,系统可以用来恢复fragment(并且也可以用来捕获fragment来处理事务,例如移除它.)  
有3种方法来为一个fragment提供一个标识:

  • 为 android:id 属性提供一个唯一ID;
  • 为 android:tag 属性提供一个唯一字符串;
  • 如果以上2个你都没有提供, 系统使用容器view的ID.

2、使用FragmentManager将fragment添加到一个已经存在的ViewGroup
  当activity运行的任何时候, 都可以将fragment添加到它的layout.只需简单的指定一个需要放置fragment的ViewGroup(通常为FrameLayout).FragmentManager提供了一个FragmentTransaction的API,以实现在activity中操作fragment事务(例如添加,移除,或代替一个fragment)。

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

然后可以使用 add() 方法添加一个fragment, 指定要添加的fragment, 和要插入的view.

MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.xx_viewgroup, fragment);
fragmentTransaction.commit();

两个参数分别是要放入的ViewGroup, 由resource ID指定和需要添加的fragment。为了使改变生效,还须调用commit()提交事务.

(二)、如果需要Fragment显示菜单,可设置hasOptionsMenu = true;

    @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setHasOptionsMenu(true);}@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {super.onCreateOptionsMenu(menu, inflater);menu.add("Ma").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);menu.add("Mb").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODOreturn super.onOptionsItemSelected(item);}

二、FragmentManager

FragmentManager能够实现管理activity中fragment. 通过调用activity的getFragmentManager()取得它的实例.FragmentManager可以做如下一些事情:
1、使用findFragmentById() (适用于在layout中提供了一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment;
2、将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令);
3、使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.

三、FragmentTransaction
  FragmentTransaction提供了对fragment进行添加,移除,替换,以及执行其他操作的api。每一个事务都是同时要执行的一套变化.可以在一个给定的事务中设置你想执行的所有变化,使用诸如 add(), remove(), 和 replace(),然后, 要给activity应用事务, 还必须要调用 commit().
  在调用commit()之前, 你可能想调用 addToBackStack(),将事务添加到一个fragment事务的back stack. 这个back stack由activity管理, 并允许用户通过按下 BACK 按键返回到前一个fragment状态.

举个例子,操作1在将layout中R.id.cont替换Fragment2,并在后台堆栈中保留之前的状态;操作2将R.id.cont替换为Fragment3,但并不保存状态。

ft = fm.beginTransaction();
ft.replace(R.id.cont, new Fragment2());
ft.addToBackStack("f2");
ft.commit();

/************************************/

ft = fm.beginTransaction();
ft.replace(R.id.cont, new Fragment3());
ft.commit();

  通过调用 addToBackStack(), replace事务被保存到back stack, 因此用户可以回退事务,并通过按下BACK按键带回前一个fragment.

 执行上面两个方法执行的Fragment2的生命周期方法为:

  onAttach -- onCreate -- onCreateView -- onActivityCreated -- onStart -- onResume --
  onPause -- onStop -- onDestoryView --
  onCreateView -- onActivityCreated -- onStart -- onResume --

  如果添加多个变化到事务(例如add()或remove())并调用addToBackStack(), 然后在调用commit()之前的所有应用的变化会被作为一个单个事务添加到后台堆栈, BACK按键会将它们一起回退.当执行一个移除fragment的事务时, 如果没有调用 addToBackStack(), 那么当事务提交后, 那个fragment会被销毁,并且用户不能导航回到它。反之,比如当移除一个fragment时,如果调用了 addToBackStack(), 那么fragment会被停止, 如果用户导航回来,它将会被恢复.

  如果添加多个fragment到同一个容器,那么添加的顺序决定了它们在view hierachy中显示的顺序.对于每一个fragment事务, 如果需要添加一个事务动画, 可以通过在提交事务之前调用setTransition()实现.

  实际上,调用 commit() 并不立即执行事务.恰恰相反, 它将事务安排排期, 一旦准备好, 就在activity的UI线程上运行(主线程).如果有必要, 可以在UI线程中调用 executePendingTransactions() 来立即执行由commit()提交的事务. 但这么做通常不必要, 除非事务是其他线程中的job的一个从属.

  只能在activity保存它的状态(当用户离开activity)之前使用commit()提交事务.如果试图在那个点之后提交, 会抛出一个异常.这是因为如果activity需要被恢复, 提交之后的状态可能会丢失.对于觉得可以丢失提交的状况, 使用 commitAllowingStateLoss().

四、Fragment之间的通信
  Fragment之间通信,我分为两种情况,一是两个Fragment同时在一个activity中,二是两个Fragment不同时存在在前台显示;

(一)、同时显示:对于同时添加显示于activity的情况,比较简单,下面是一个例子

>>.布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"tools:context=".MainActivity" ><fragmentandroid:id="@+id/fragment1"android:name="com.fragment.Fragment1"android:layout_width="0dip"android:layout_height="match_parent"android:layout_weight="1" /><fragmentandroid:id="@+id/fragment2"android:name="com.fragment.Fragment2"android:layout_width="0dip"android:layout_height="match_parent"android:layout_weight="1" /></LinearLayout>

.布局内容

    <Buttonandroid:id="@+id/modify"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="修改TextView" /> <!--frag1对应布局内容--><TextViewandroid:id="@+id/value"android:layout_width="match_parent"android:layout_height="match_parent" /> <!--frag2对应布局内容-->

.Fragment1

public class Fragment1 extends Fragment implements OnClickListener {/*** 当fragment被创建的时候调用此方法,返回当前fragment显示的内容*/@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View v = inflater.inflate(R.layout.fig1, null);Button btn = (Button) v.findViewById(R.id.modify);btn.setOnClickListener(this);return v;}@Overridepublic void onClick(View v) {Fragment2 f2 = (Fragment2) getActivity().getFragmentManager().findFragmentById(R.id.fragment2);f2.setText("测试修改TextView值");}
}

.Fragment2

public class Fragment2 extends Fragment {private TextView tv;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View v = inflater.inflate(R.layout.fig2, null);tv = (TextView) v.findViewById(R.id.value);return v;}public void setText(String str) {tv.setText(str);}
}

在"接收消息"的Fragment中定义public方法,在"发送消息"的Fragment中通过getActivity().getFragmentManager().findFragmentById(id)查找到Fragment并传送消息;
(二)、不同时显示
比如说,当前Activity的一个页面某部分内容为Fragment1,点击Fragment1中的某一个按钮,需要将Fragment所在区域显示为Fragment2,同时需要给Fragment2传参数过去,这时通过findFragmentById就不能达到要求了;
这时就需要用到接口编程,定义一个接口并让Activity去实现这个接口,在Fragment中通过getActivity()获取Fragment所依托的Activity对象并转换为所定义的接口对象,在需要进行通讯的地方,调用接口的方法即可;

Android Fragment 使用详解相关推荐

  1. Android LiveData组件详解以及LiveDataBus

    转载请标明出处:https://blog.csdn.net/zhaoyanjun6/article/details/99749323 本文出自[赵彦军的博客] 一.LiveData简介 LiveDat ...

  2. android开发照相机啊,Android照相机开发详解(一)

    Android相机开发详解(一) Android相机开发详解(一) 请支持原创,尊重原创,转载请注明出处:http://blog.csdn.net/kangweijian(来自kangweijian的 ...

  3. Android相机开发详解(一)

    Android相机开发详解(一) 请支持原创,尊重原创,转载请注明出处:http://blog.csdn.net/kangweijian(来自kangweijian的csdn博客) Android相机 ...

  4. android组件模板,提高效率必备神器 ---- Android Studio模板详解

    原标题:提高效率必备神器 ---- Android Studio模板详解 Android Studio模板大家应该很熟悉,你新建一个project或者module的时候,AS会帮你提供几个选项供你选择 ...

  5. Android:Frament详解

    Android:Frament详解 Fragment是什么 Fragment运行 Fragment是什么 具备生命周期:依托Activity运行 Fragment运行 <?xml version ...

  6. android preference属性,Android进阶——Preference详解之Preference系的基本应用和管理(二)...

    并非我们第一次打开相应界面之后就会自动创建对应的SharedPreferences文件,而是在我们改变了原有状态时候喎�"/kf/ware/vc/" target="_b ...

  7. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  8. JMessage Android 端开发详解

    JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...

  9. 《Java和Android开发实战详解》——2.5节良好的Java程序代码编写风格

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.5节良好的Java程序代码编写风格,作者 陈会安,更多章节内容可以访问云栖社区"异步社区&quo ...

最新文章

  1. Mysql服务器问题(2013.3.5日发现)
  2. Android通过JNI调用驱动程序(完全解析实例)
  3. 使用docker搭建Hadoop
  4. Mac下安装配置Python2和Python3并相互切换使用
  5. ubuntu Linux18.10/19.10下的护眼宝
  6. Wannafly挑战赛21: C. 大水题(DP)
  7. MariaDB 10.3 instant ADD COLUMN亿级大表毫秒级加字段
  8. 中国工业企业数据库stata处理
  9. i5200u处理器 HD5500集成显卡安装黑苹果教程
  10. vmware 常用知识
  11. Spring学习笔记-IoC
  12. 服务器端方法级权限控制----------@Secured注解的使用
  13. 单片机c语言拟合二次曲线y=a0+a1x+a2x^2
  14. 印度软件腾飞不是偶然
  15. Mac环境安装imagemagick及使用imagemagick拼接图片
  16. forEach,$.each()以及$().each()的比较
  17. 什么是智能安全帽,如何选购智能安全帽
  18. 织梦学习 织梦留言板【详解】
  19. PyEcharts——地图-数据可视化-画图
  20. 树莓派终端设置字体大小

热门文章

  1. Linux信号的产生和处理
  2. linux新建脚本文件,linux shell脚本编程2—修改文件时间和创建新文件即touch命令的使用...
  3. dfa matlab用法,关于使用MF-DFA方法计算广义Hurst指数的MATLAB操作问题
  4. 大学生学java要去培训机构吗?
  5. 学习web前端开发大半年,迷茫了,感觉什么都没学会怎么破?
  6. clion远程调试linux内核,Clion + 树莓派/Ubuntu 远程调试
  7. python和c语言全局变量,Python如何实现C/C++全局变量?
  8. c语言程序如何实现分组,c程序-实现随机分组.ppt
  9. php点赞,php如何实现点赞
  10. plsql 无法解析指定的连接标识符_TNS03505:无法解析名称