前言:
之前搞项目的时候,就使用了这个Fragment,中间遇到了许多坑,把坑都解决了,现在写一篇较为简单的Fragment使用总结
Fragment的简单介绍:
简单来说,Fragment其实可以理解为一个具有自己生命周期的控件,只不过这个控件又有点特殊,它有自己的处理输入事件的能力,有自己的生命周期,又必须依赖于Activity,能互相通信和托管。
使用Fragment可以精简Activity文件的代码,便于更好的阅读,同时,有着更好的速度加载
使用Fragment的另外一种情况是可以在平板和手机显示不同的界面,由于没有接触平板电脑APP的开发,所以这个方面就不说明了。
Fragment的使用:
目录:
1.创建Fragment及Fragment对应的布局文件
2.使用静态方法创建Fragment(xml文件中使用)
3.动态创建并使用Fragment(java代码)
4.通过FragmentManager的方法来找到静态方法创建的Fragment实例
5.Fragment像activity一样使用
6.Fragment的生命周期
7.Fragment的消息传递(重点)
8.Fragment点击事件冲突处理
1.创建Fragment及Fragment对应的布局文件
创建的话我们可以通过手动创建一个Fragment文件及一个xml布局文件,之后在Fragment的onCreateView方法中调用inflate来返回一个View
其实Android Studio给我们提供了一个很好的自动化生成Fragment及布局文件工具,我们直接new,选择Fragment->blank即可
至于其他的几种Fragment,有兴趣可以百度找资料
之后我们来到了新建的界面,Android Studio会自动生成Fragment与Fragment对应的布局,而且代码中也是帮我们加上了之前的那一行代码来刷新视图
为了方便下面的使用,我们简单地将fragment__test这个布局文件的背景设置为红色
2.使用静态方法创建Fragment(xml文件中使用)
<fragment
android:id="@+id/fragmetn1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.wan.fragmenttest.TestFragment"
tools:layout="@layout/fragment_test"/>
上面的代码即是添加Fragment的代码,和我们使用控件差不多,就是需要使用name这个属性来指定相关的Fragment
id是必须的,没有的话就会出现闪退,tools:layout是用来显示当前的Fragment,没有的话预览图就是灰色的,可用可不用,不过方便查看效果还是用吧
我们这样就是成功的用静态方法使用了一个Fragment
3.动态创建并使用Fragment(java代码)
首先,我们把之前的在activity布局文件中的Fragment给删除,换成一个framelayout,并给其定义了一个id
之后,我们new一个Fragment,使用FragmentTransaction的add或者是replace方法,将其放入一个framelayout之中
FragmentTransaction由FragmentManager的beginTransaction方法获得
add方法第一个参数为一个layout布局,就是我们之前的那个framelayout的id,第二个则是fragment,我们之前new的一个TestFragment,commit提交事务,不提交事务是无效的,不信的话可以自行测试
PS:这里需要注意一下,Fragment有两个不同的包,一个是app,另外一个是v4
由图中可以看到,这两个有什么区别呢?
android.support.v4.app.fragment包是为可以向下兼容至1.6系统.
android.app.fragment包是3.0系统以后的才能使用的,不过这也无所谓了,现在android4.0已占用了百分之九十九的市场
我们使用app这个包就好
如果使用的是v4包的话,获得FragmentManager需要使用getSupportFragmentManager方法
如果使用的是app包的话,直接使用getFragmentManager方法来获得FragmentManager
动态的我们只能运行来查看测试结果,可以看到与之前使用静态方法是一样的界面
4.通过FragmentManager的方法来找到静态方法创建的Fragment实例
两种方法:
findFragmentById方法与findFragmentByTag
我们在xml中定义一个id,之后可以通过findFragmentById方法找到实例
同样的道理,我们在xml中给Fragment定义一个Tag,之后就可以通过findFragmentByTag方法来找到实例
使用Fragment有两种方法我们可以通Fragment
5.Fragment像activity一样使用
如果我们的Fragment中使用了button等控件,那么,我们可以像activity中,通过findViewbyid方法来找到控件的实例,并为其设置监听器
不过,需要注意的是,Fragment只有在View被创建之后才能通过findviewbyid找到控件的实例,也就是只有在onViewCreated中才能使用findviewbyid方法
6.Fragment的生命周期
Fragment
1. 界面打开
onCreate() 方法执行!
onCreateView() 方法执行!
onActivityCreated() 方法执行!
onStart() 方法执行!
onResume() 方法执行!
2. 按下主屏幕键/锁屏
onPause() 方法执行!
onStop() 方法执行!
3. 重新打开
onStart() 方法执行!
onResume() 方法执行!
4. 按下后退键
onPause() 方法执行!
onStop() 方法执行!
onDestroyView() 方法执行!
onDestroy() 方法执行!
onDetach() 方法执行!
在Activity中加入Fragment,对应的生命周期
1. 打开
Fragment onCreate() 方法执行!
Fragment onCreateView() 方法执行!
Activity onCreate() 方法执行!
Fragment onActivityCreated() 方法执行!
Activity onStart() 方法执行!
Fragment onStart() 方法执行!
Activity onResume() 方法执行!
Fragment onResume() 方法执行!
2. 按下主屏幕键/锁屏
Fragment onPause() 方法执行!
Activity onPause() 方法执行!
Fragment onStop() 方法执行!
Activity onStop() 方法执行!
3. 再次打开
Activity onRestart() 方法执行!
Activity onStart() 方法执行!
Fragment onStart() 方法执行!
Activity onResume() 方法执行!
Fragment onResume() 方法执行!
4. 按下后退键
Fragment onPause() 方法执行!
Activity onPause() 方法执行!
Fragment onStop() 方法执行!
Activity onStop() 方法执行!
Fragment onDestroyView() 方法执行!
Fragment onDestroy() 方法执行!
Fragment onDetach() 方法执行!
Activity onDestroy() 方法执行!
7.Fragment的消息传递
在activity中,我们使用Bundle来携带数据进行传递,在Fragment中,也是使用的Bundle
如何使用呢?
首先,为Fragment创建一个静态方法newInstance
我们可以直接输入newInstance,就会出现代码补全提示,选择之后就会补全了代码
方法如上所示,首先,创建了一个Bundle的对象和一个TestFragment的对象,调用Fragment中的setArguments,将bundle存放进去,之后,返回一个TestFragment
这里的bundle还没有携带任何的数据,现在我们想传入一个String的数据,代码如下所示
这样我们就完成了传递数据,但是,还差一步,我们得接收数据,由之前的 生命周期,我们可以知道,onCreate方法是第一步执行的,所以,在onCreate方法中接收Bundle传来的数据
接收数据前,我们得在Fragment文件中声明几个全局变量,用来接收数据
这样便是完成了消息的传递
补充参考:Android开发——fragment中数据传递与刷新UI(更改控件)
8.Fragment点击事件冲突处理
图中,有两个日记,点击就会弹出查看日记
由图中可以看到,我们的点击透过了当前的Fragment,这显然不是我们想要的结果,我们应该怎么做呢?答案很简单,就是给当前显示出的那个Fragment添加一个onTouch监听器
PS:在Fragment中可以通过getActivity方法获得context