对于Fragment的总结

1、对比v4包与app包下的Fragment,有哪些不同点,使用时该注意哪些?

①android.support.v4.app.Fragment:V4的兼容性更强,其可以兼容到android:minSdkVersion="4",就是android的版本号是1.6.
android.app.Fragment的兼容性的最低版本是android:minSdkVersion="11",就是android的3.0版本
②在运用的时候倒入的包不同
③继承的父类不同,v4的Fragment的FragmentManager fm = getSupportFragmentManager(),并且当前的Activity需要继承自FragmentActivity.
android.app.Fragment是通过FragmentManager fm = getFragment(),并且当前的Activity继承自Activity即可。
④使用的时候:V4的Fragment可以通过静态加载的方法在布局文件中<fragment>来使用。
但是android.app.Fragment需要也能通过<fragment>标签来加载,需要在程序中动态的通过add,replace的方法来使用。但是其继承的是Activity.
⑤注意,不管用哪一个包下面的,都必须完全运用那个包下面的。
⑥对于v4,需要在project structure中的dependencies中添加v4的包。

2、为什么创建Fragment时传递参数要用setArguments()

在导入V4的Fragment的时候是没有有参数的构造函数的,所以不能通过构造函数的方式去传递值。
在Activity在异常情况下退出的时候,比如切换横屏幕,竖屏幕的时候,会将临时数据存放在Bundle中,如果不用setArguments的时候,则会出现数据丢失,切换屏幕之后就无法显示了。

3、 将Fragment添加到Activity中的方式有哪些,有何区别。

静态添加:将Fragment作为一种组件,在布局文件中进行添加,不过要指明android:name,即将Fragment放到这个布局中,这样的话,在静态添加的fragment中就不能实现fragment的切换,替代等。
动态添加:需要在布局文件中有一个Fragment的容器。在动态添加的时候,首先需要一个Fragment管理器,即FragmentManager,在android.app.Fragment中直接通过:FragmentManager fm = getFragmentManager(),而在v4的包中需要通过FragmentManager fm = getSupportManager()的形式获取。再在拿到FragmentManager的基础之上,得到FragmentTransication,来对Fragment来做一系列的操作。
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

4、FragmentTransaction里面一些基本方法说明,比如add()/show()
这些方法是在动态加载Fragment中,对Fragment做的一系列的事务性操作

add():向Activity中添加一个Fragment,有三个重载的方法。
remove():从Activity中移除一个Fragment
replace():使用一个Fragment替换当前的一个Fragment
hide():隐藏当前的Fragment,不会调用生命周期的方法
show():显示之前隐藏的Fragment,不会调用生命周期的方法
detach():会将View从UI中移除,detach()之后可以调用attach()来进行恢复
attach():重建View视图,附加到UI上并显示
5、动态添加add()方法,各参数的意义,tag作用?(findFragmentByTag)
有三个重载的add()方法:

add(Fragment,Tag):Tag的作用就是可以通过getFragmentManager.findFragmentByTag的方式来获取一个fragment,然后把它当成一个view来操作。(无UI布局,onCreateView是无效的)
add(id,Fragment):注意前面的id是一个ViewGroup的id,后面是一个fragment的对象。
add(id,Fragment,Tag):
当Fragment没有UI的时候,可以通过findFragmentByTag来找到这个Fragment,这里不需要在Fragment中写onCreateView的方法,通过add(fragment,Tag)的方式去添加Fragment.
6、FragmentTransaction,一次事务中可以进行多个操作,比较commit()、commitNow()、commitAllowingStateLoss(),区别?
事物的提交方式有4种,commit(),commitAllowingStateLoss(),commitNow(),commitNowAllowingStateLoss()

commit():在主线程中异步执行,需要等待主线程的调度,其在使用的时候FragmentManager会检查是否已经保存了其状态,如果状态已经保存了,则就抛出IllegalStateException异常。就是说commit()需要在宿主Activity保存状态之前调用,否则就会报错。(因为如果Activity出现异常需要恢复状态,在保存状态之后的commit()将会丢失,这和调用的初衷不相符合。

commitAllowingStateLoss():也是一个异步操作,但是其允许Activity保存状态之后调用,也就是说遇到状态丢失不会报错。(在状态出错是可以接受的情况下使用)

commitNow():是同步执行的操作,需要在Activity执行保存状态之前来进行操作。否则会抛出异常。(FragmentManager.excutePendingTranscantions()也表示一下执行提交操作,但是其会把所有的任务一次性提交,这样有可能会有副作用)遇到状态丢失不会报错。

commitNowAllowingStateLoss():是一个同步操作,但是允许在Activity保存状态之后调用。
7、 AllowingState原因,解决AllowingState异常有哪些方法
当Activity异常销毁的时候会调用onSaveInstanceState(),来保存状态信息,但是如果commit在保存状态信息之后操作,那么久相当于给Activity重新添加了一个fragment,这个时候的fragment的状态和上一个的fragment的状态不一样,所以就会报状态不正确的异常。可以通过commitAllowingState的方式。
8、onSaveInstanceState()、onPause()、onStop()三者的生命周期顺序?
onSaveInstanceState()并不是每一次Activity的生命周期都会调用的,其只是用于在异常情况下销毁Activity的时候调用,保存的是和当前Activity状态相关的临时数据。
onPause(),onStop()也可以用于保存一些数据,但是保存的都是持久化的数据。
若启动ActivityB之后,选择点击Home按钮,程序退到后台,那么执行顺序是:B:onPause -> B:onSaveInstanceState -> B:onStop。
程序在后台的时候,选择主动杀死程序进程,然后再从桌面点击应用启动,会显示之前的ActivityB,执行顺序是:B:onCreate -> B:onStart –> B:onRestoreInstanceState - > B:onResume。
onSaveInstanceState()在Activity的onPause()的情况后再调用。
onRestoreSaveInstanceState()在Activity的onResume之前调用。
9、Fragment事务中加不加addToBackStack()的区别,popBackStack()?
addToBackStack()的用途是是否将一次的事务操作加入到回退栈,官方的说法是是否要在回退的时候显示上一个Fragment.
addToBackStack()保存的是一系列针对一个fragmentTransaction的操作记录,表示是否将上一次的Fragment加入到回退栈中,如果加入,则按back键的时候,前面的Fragment就会显示出来。如果不加入,前面的fragment就不会显示出来。
popBackStack();  弹出堆栈中的一个并且显示,也就是代码模拟按下返回键的操作。
10、 Fragment向Activity传递数据、Activity向Fragment传递数据、Fragment之间通信
Fragment之间的通信:

可以通过Activity这个中间媒介来实现。在一个Fragment中通过Activity(getActivity()方法来获得Activity的实例)获取到另外一个Fragment,再调用另外一个Fragment的相关方法来实现通信。
Fragment向Activity传递数据:

通过接口的方式,在外部声明一个接口,在Fragment的Attach()的方法中去实例化Listener(该接口强转为activity类型便可和Activity有交际),在Fragment的onCreateView的方法中调用接口中的返回发,并放置相应的参数。接口的实现方法在Activity中来实现,拿到参数做一些与Activity更新界面相关的事情。
Activity项Fragment中传递数据:

1、setArguments(Bundle)的方式去传递数据,然后在Fragment的onCreateView的方法中去getArgments()获取Bundle.

2、在Activity中定义返回某个需要传递参数的值,然后在Fragment的onAttach()方法中去调用这个方法,取到这个值。

11、DialogFragment
①可以有类似于Fragment一样的生命周期,便于管理
②DialogFragment可以自定义显示的布局,与普通的Dialog不一样,(普通的Dialog只是通过builder的方式去构建对话框)
③一般的Dialog在切换屏幕(Activity异常销毁再重建)的时候不会保存状态。
④在DialogFragment在切换屏幕的时候会保存状态。

12、ViewPager+Fragment相关
一般用到上述的时候需要在Fragment左右滑动的时候去切换Fragment.
首先要在布局文件中加一个组件ViewPager的组件,这里需要导入的是v4下的包,主要是在使用Adapter的时候用的是FragmentPagerAdapter来关联ViewPager和Fragment,这个Adapter继承自ViewPager,在V4的包下。
在Activity中获取到ViewPager组件,再把Fragment添加进去。
可以对ViewPager设置监听滑动,setOnPageChanged(..)

13、 FragmentPagerAdapter和FragmentStatePagerAdapter的区别“
FragmentPagerAdapter:在Fragment较少的情况下使用,主要是会把Fragment加入到内存,占用内存,Fragment不在viewPager.setOffscreenPageLimit()的保护的范围内会调用FragmentManager的detach()方法,相应的Fragment的onDestroyView会执行,但Fragment实例仍在
FragmentStatePagerAdapter:在Fragment较多的情况下使用,不会把Fragment加载到内存,当其中一个Fragment划过去的时候,这个Fragment就会被销毁,当需要可见的时候再重新创建这个fragment的实例。

14、懒加载
懒加载的意思就是需要的时候才去加载
在ViewPager需要包含多个Fragment的时候,其在第一个Fragment创建的时候,其他的Fragment也相应的创建好了,及走了onAttach,onCreate,onCreateView,onActivityCreate,onStart,,onResume.Fragment的 onResume()表示的是当前Fragment处于可见且可交互状态,但由于ViewPager的缓存机制,它已经失去了意义,也就是打开第一个Fragment,但其实其他的Fragment的数据也都已经加载好了。如果加载数据的操作都比较耗时或者都是类似图片的占用大量内存,这时就应该考虑想想是否该实现懒加载。
懒加载的实现方式:通过setVisible的方式,当用户对于当前的Fragment可见的时候去加载。如果可见,则再在onCreateView中去请求数据,初始化界面等操作。
15、 setUserVisibleHint调用时机
在切换Fragment的时候会调用,当fragment即将可见(在onAttach()之前),和即将不可见的时候就会调用。主要是设置一个标志位,用于懒加载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 导语: Fragment作为Android最基本,最重要的基础概念之一,在开发中经常会和他打交道。本文从为什么出现...
    JYGod丶阅读 146,505评论 7 166
  • 驾考逸事一一之六 似乎掉队了 入了驾校门,同学一大群, 年龄跨度大,青年占九分, 忝自列其中,迟钝大龄人, 欲找同...
    沁园春M阅读 146评论 1 2
  • 愿在衣而为领,承华首之余芳;悲罗襟之宵离,怨秋夜之未央。 愿在裳而为带,束窈窕之纤身;嗟温凉之异气,或脱故而服新。...
    薛小七阅读 480评论 0 0
  • 现在很想问自己一个问题,你在想什么? 结束了愉快的综艺,我在想过后为什么自己会难过又无奈? 投出简历后,我在想自...
    小虾米_cc17阅读 218评论 0 0