Fragment的replace和add方法的区别
回答提示
在项目中进行Fragment切换的时候,可以用replaced()方法来切换,也可以用add()。
区别
add是吧一个Fragment添加到一个容器Container中
replace是先remove相同id的所有Fragment,然后在add当前这个Fragment
需要注意
使用replace()切换的话,Fragment都会重新实例化,重新加载数据,如何每次加载的数据都是从网络中获取的,这样就会带来性能的问题。
官方说明:replace()方法,只是在上一个Fragment不在使用时才调用。如果上一个Fragment还需要使用的话,应该使用add()方法切换。
Activity和Fragment生命周期有哪些?
Activity:
onCreate->onStart->onResume->onPause->onStop->onDestroy。
Fragment:
onAttach->onCreate->onCreateView->onActivityCreated>onStart->onResume->onPause->onStop->onDestroyView
Fragment 跟 Activity 之间是如何传值的?
面试经验:
这个问题真实场景经常见,面试官就想看看大家是否有过真实开发经验,大家先说说如何传值,先让面试官感觉大家有经验确实干过,然后在介绍下在真实开发的场景哪里用过,然后也介绍下一般使用EventBus或者RxBus这样让人感觉满满的干货,谈工资也比较好谈,目前开发中用一个activity加载几个fragment是非常常见的,例如:订单中心,主页面架构等等。不可避免的就需要用到activity与fragment之间进行某些值的传递,那么两者之间是如何值传递的呢?
答案解析
当 Fragment 跟 Activity 绑定之后,在 Fragment 中可以直接通过 getActivity()方法获取到其绑定的 Activity 对象,这样就可以调用 Activity 的方法了。在 Activity 中可以通过如下方法获取到 Fragment 实例
FragmentManager fragmentManager=getFragmentManager();
Fragment fragment=fragmentManager.findFragmentByTag(tag);
Fragment fragment=fragmentManager.findFragmentById(id);
获取到 Fragment 之后就可以调用 Fragment 的方法。也就实现了通信功能。
另外也可以调用 fragment.setArguments(Bundle)方法,将数据绑定到 Fragment 域中。
更多资料参考:Activity和Fragment之间的数据通信
描述一下 Fragment 的生命周期
描述一下 Fragment 的生命周期
面试官问这个问题就想看看大家对Fragment是否熟悉,毕竟Fragment用户体验很好,开发经常用,问这个问题还算正常。
日常开发中,fragment的使用是必不可少的,所以它也是基础面试中几乎必问的问题之一。fragment的生命周期和activity类似,有多出来几个生命周期,我们只需要对这几个多出来的生命周期掌握了就可以了,其他的都差不多。
- onAttach()
Fragment和Activity建立关联的时候调用,被附加到Activity中去。 - onCreate()
系统会在创建Fragment时调用此方法。可以初始化一段资源文件等等。 - onCreateView()
系统会在Fragment首次绘制其用户界面时调用此方法。 要想为Fragment绘制 UI,从该方法中返回的 View 必须是Fragment布局的根视图。如果Fragment未提供 UI,您可以返回 null。 - onViewCreated()
在Fragment被绘制后,调用此方法,可以初始化控件资源。 - onActivityCreated()
当onCreate(),onCreateView(),onViewCreated()方法执行完后调用,也就是Activity被渲染绘制出来后。 - onPause()
系统将此方法作为用户离开Fragment的第一个信号(但并不总是意味着此Fragment会被销毁)进行调用。 通常可以在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。 - onDestroyView()
Fragment中的布局被移除时调用。 - onDetach()
Fragment和Activity解除关联的时候调用。
ViewPager和Fragment使用过程中会遇到哪些问题
回答提示:
1. 适配器的选择
使用ViewPager加载多个Fragment时,我一般选择FragmentPagerAdapter。
需要大家注意:
FragmentPagerAdapter:该类内的每一个生成的 Fragment 都将保存在内存之中,因此适用于那些相对静态的页,数量也比较少的场景
但是,如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,这时候,我们选择怎么是的适配器呢?
应该使用FragmentStatePagerAdapter
FragmentStatePagerAdapter:会把已经创建的Fragment进行保存。会保持Fragment的状态 通过源码分析发现:
FragmentStatePagerAdapter这个类抽象出了一个getItem()方法,用于创建对应的Fragment 而FragmentStatePagerAdapter的.instantiateItem()方法实现中,调用了getIitem()方法。 调用该instantiateItem()方法时,判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();
如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。 FragmentStatePagerAdapter会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法。
2. Fragment数据的缓存
Fragment在初始化View对象,把该对象作为一个成员变量进行保存。 再一次初始化Fragment对应的View对象时,判断当前成员变量View对象是否为空。 如果为空,创建新的View对象,否则,不在创建。这样就可以做到对Fragemnt进行数据缓存
这样做的好处:避免了每次加载Fragment都要重新创建View,加载数据了。提高了性能,以及减少了内存的开销。
3. ViewPager预加载
我们知道,系统的ViewPager默认提供预加载机制。但是,根据业务需要,取消掉对应的预加载机制。 可以这样做:
替换掉系统原生的Viewpager类。将该类中的一个变量mOffscreenPageLimit 设置为0,不进行预加载
4. Fragment嵌套Fragment
- 在Fragment中嵌套Fragment时,一定要使用getChildFragmentManager();
- 否则,会在ViewPager中出现fragment不会加载的情况,即fragment出现空白页的情况。