Android Fragment

来源:互联网 发布:2003版办公软件 编辑:程序博客网 时间:2024/06/06 09:48

1Fragment概述

FragmentAndroid3.0后引入的一个新的API,他出现的初衷是为了适应大屏幕的平板电脑, 当然现在他仍然是平板APP UI设计的宠儿,而且我们普通手机开发也会加入这个Fragment, 我们可以把他看成一个小型的Activity,又称Activity片段!想想,如果一个很大的界面,我们 就一个布局,写起界面来会有多麻烦,而且如果组件多的话是管理起来也很麻烦!而使用Fragment我们可以把屏幕划分成几块,然后进行分组,进行一个模块化的管理!从而可以更加方便的在 运行过程中动态地更新Activity的用户界面!另外Fragment并不能单独使用,他需要嵌套在Activity中使用,尽管他拥有自己的生命周期,但是还是会受到宿主Activity的生命周期的影响,比如Activitydestory销毁了,他也会跟着销毁!

 

2、Fragment生命周期

 

Activity加载Fragment的时候,依次调用下面的方法: onAttach -> onCreate -> onCreateView ->onActivityCreated -> onStart ->onResume

②当我们弄出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点onPause

③当对话框关闭,Activity又获得了焦点: onResume

④当我们替换Fragment,并调用addToBackStack()将他添加到Back栈中 onPause -> onStop -> onDestoryView !!注意,此时的Fragment还没有被销毁哦!!!

⑤当我们按下键盘的回退键,Fragment会再次显示出来: onCreateView -> onActivityCreated -> onStart -> onResume

⑥如果我们替换后,在事务commit之前没有调用addToBackStack()方法将Fragment添加到back栈中的话;又或者退出了Activity的话,那么Fragment将会被完全结束, Fragment会进入销毁状态 onPause -> onStop ->onDestoryView -> onDestory -> onDetach

 

3Fragment要点

3.1 特点

· 3.0版本后引入,minSdk要大于11

· Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment,但这个被嵌套 的Fragment也是需要嵌套在Activity中的,间接地说,Fragment还是需要嵌套在Activity!!受寄主Activity的生命周期影响,当然他也有自己的生命周期!另外不建议在Fragment里面 嵌套Fragment因为嵌套在里面的Fragment生命周期不可控!!!

· 官方文档说创建Fragment时至少需要实现三个方法:onCreate( ),onCreateView( ),OnPause( );不过貌似只写一个onCreateView也是可以的...

· Fragment的生命周期和Activity有点类似:三种状态:
Resumed:在允许中的Fragment可见
Paused:所在Activity可见,但是得不到焦点
Stoped: ①调用addToBackStack(),Fragment被添加到BcakActivity转向后台,或者该Fragment被替换/删除
ps:停止状态的fragment仍然活着(所有状态和成员信息被系统保持着),然而,它对用户 不再可见,并且如果activity被干掉,他也会被干掉.

3.2 子类

· 对话框:DialogFragment

· 列表:ListFragment

· 选项设置:PreferenceFragment

· WebView界面:WebViewFragment

3.3

我们到底是使用android.app下的Fragment还是用的android.support.v4.app包下 的Fragment呢?其实都可以,前面说过FragmentAndroid 3.0(API 11)后引入的,那么如果开发的app需要 在3.0以下的版本运行呢?比如还有一点点市场份额的2.3!于是乎,v4包就这样应运而生了,而最低可以兼容到1.6版本!至于使用哪个包看你的需求了,现在3.0下手机市场份额其实已经不多了,随街都是4.0以上的,6.0十月份都出了,你说呢...所以这个时候,你可以直接使用app包下的Fragment然后调用相关的方法,通常都是不会有什么问题的;如果你Fragment用了app包的, FragmentManagerFragmentTransaction都需要是app包的!要么用全部用app,要么全部用v4,不然可是会报错的哦!当然如果你要自己的app对于低版本的手机也兼容的话,那么就可以选择用v4包!

·如果你使用了v4包下的Fragment,那么所在的那个Activity就要继承FragmentActivity!案例:今天在xml文件中静态地载入fragment,然后重写了Fragment,但是在加载Activity的时候就报错了, 大概的提示就是Fragment错误还是找不到什么的,name属性改了几次还是错!最后才发现是用了v4的包的缘故,只需让自己的Activity改成FragmentActivity即可!

4创建Fragment

4.1静态加载

 

4.2动态加载

 

 

4.3Fragment的管理

 

4.4Fragment与Activity交互

 

FragmentFragment之间的数据互传

其实这很简单,找到要接受数据的fragment对象,直接调用setArguments传数据进去就可以了 通常的话是replace,fragment跳转的时候传数据的,那么只需要在初始化要跳转的Fragment后调用他的setArguments方法传入数据即可!
如果是两个Fragment需要即时传数据,而非跳转的话,就需要先在Activity获得f1传过来的数据,再传到f2,就是以Activity为媒介~

5Fragment注意事项

1)使用FragmentPagerAdapter+ViewPager的注意事项

使用FragmentPagerAdapter+ViewPager时,切换回上一个Fragment页面时(已经初始化完毕),不会回调任何生命周期方法以及onHiddenChanged(),只有setUserVisibleHint(boolean isVisibleToUser)会被回调,所以如果你想进行一些懒加载,需要在这里处理。

在给ViewPager绑定FragmentPagerAdapter时,new FragmentPagerAdapter(fragmentManager)FragmentManager,一定要保证正确,如果ViewPagerActivity内的控件,则传递getSupportFragmentManager(),如果是Fragment的控件中,则应该传递getChildFragmentManager()。只要记住ViewPager内的Fragments是当前组件的子Fragment这个原则即可。

你不需要考虑在“内存重启”的情况下,去恢复的Fragments的问题,因为FragmentPagerAdapter已经帮我们处理啦。

2)是使用单Activity+多Fragment的架构,还是多模块Activity+多Fragment的架构?

Activity+多Fragment一个app仅有一个Activity,界面皆是FramentActivity作为app容器使用。

优点:性能高,速度最快。参考:新版知乎 googleapp

缺点:逻辑比较复杂,尤其当Fragment之间联动较多或者嵌套较深时,比较复杂。

多模块Activity+多Fragment一个模块用一个Activity,比如
1、登录注册流程:
LoginActivity + 登录Fragment +注册Fragment +填写信息Fragment+ 忘记密码Fragment
2、或者常见的数据展示流程:
DataActivity + 数据列表Fragment +数据详情Fragment...

优点:速度快,相比较单Activity+Fragment,更易维护。

多模块Activity+多Fragment是最合适的架构,开发起来不是很复杂,app的性能又很高效。(出自http://www.jianshu.com/p/fd71d65f0ec6

6、一些使用建议

1、对Fragment传递数据,建议使用setArguments(Bundle args),而后在onCreate中使用getArguments()取出,在内存重启前,系统会帮你保存数据,不会造成数据的丢失。和ActivityIntent恢复机制类似。

2、使用newInstance(参数) 创建Fragment对象,优点是调用者只需要关系传递的哪些数据,而无需关心传递数据的Key是什么。

3、如果你需要在Fragment中用到宿主Activity对象,建议在你的基类Fragment定义一个Activity的全局变量,在onAttach中初始化,这不是最好的解决办法,但这可以有效避免一些意外Crash

7add(), show(), hide(), replace()的那点事


1、区别
show(),hide()最终是让Fragment的View setVisibility(true还是false),不会调用生命周期;

replace()的话会销毁视图,即调用onDestoryViewonCreateView等一系列生命周期;

add() replace()不要在同一个阶级的FragmentManager里混搭使用。

2、使用场景
如果你有一个很高的概率会再次使用当前的Fragment,建议使用show()hide(),可以提高性能。

在我使用Fragment过程中,大部分情况下都是用show()hide(),而不是replace()

注意:如果你的app有大量图片,这时更好的方式可能是replace,配合你的图片框架在Fragment视图销毁时,回收其图片所占的内存。

3onHiddenChanged的回调时机
当使用add()+show()hide()跳转新的Fragment时,旧的Fragment回调onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged(),这点要切记。

4Fragment重叠问题
使用show()hide()带来的一个问题就是,如果你不做任何额外处理,在内存重启后,Fragment会重叠;(该BUGsupport-v4 24.0.0+以上 官方已修复)