Android 多个Fragment嵌套导致的三大BUG
Android有碎片化的问题,当然本文说的碎片化不是指的系统版本碎片化的问题,而是Fragment组件碎片化的问题。
很久之前,在Android 3.1系统发布的时候,Google推出了使用Fragment来更加容易地开发平板和手机应用,虽然Activity还是页面结构的主体,但是却可以在其基础上使用多个Fragment来构建页面,这些Fragment都是有各自的生命周期的。
最常见的是列表和详情页面使用Fragment,如果在手机设备上,这个两个一般都是在独立的Activity页面中,但是在平板上这两个Fragment往往都是嵌套在一个Activity中。
当然,在开发过程中,正常情况下都是没有问题的。
1、特殊的Fragment
如果想要使用Fragment来开发应用并且适配低版本系统,必须要使用Google提供的Support Library(V4).
Support Library这个兼容库设计地有些莫名其妙,它为了提供向后兼容的特性,替换了整个Fragment框架。比如,运行在3.1之后的系统系统上,使用的Fragment还是Support Library所提供的,而不是基于系统自身的(这一点在讲到后面的时候非常重要)。
2、Fragment的嵌套
使用Fragment时最繁琐复杂的就是多个Fragment之间的相互通信,必须通过Activity作为中间者传递。嵌套的Fragment一开始是不支持的,因为会导致了各式各样的bug。直到API 17,也就是Jelly Bean 4.2,终于开始支持嵌套的Fragments,并且这个功能也被添加到了Support Library里面。使用Fragment来搭建页面的梦想实现的一天终于到来了,这种方式有一个巨大的好处,就是解放Activity,使用多个Fragment组件来承载UI和逻辑。
梦想很美好,现实很残酷!
3、Fragment嵌套BUG之一:突变的动画效果
问题: 交互体验做到极致的APP,都会使UI具有平滑顺畅的动画效果。FragmentManager是允许通过设置转场过渡动画的。但是,退出动画会导致嵌套的Fragment在动画刚刚开始时就瞬间消失。
原因: Fragments有一个嵌套的生命周期,导致嵌套的Fragment会在其宿主Fragment前执行相应的生命周期,比如onStop。由于宿主Fragment的FragmentManager无法识别嵌套的Fragment,在动画开始执行的时候,嵌套的Fragment的视图树会直接跳过动画阶段,但是宿主Fragment的动画却还在执行。所以宿主Fragment和嵌套Fragment动画的步调是完全不一致的。
解决: 参考Stack Overflow上的一个解决方案:http://stackoverflow.com/questions/14900738/nested-fragments-disappear-during-transition-animation 原理是缓存宿主Fragment的当前可见状态,但是这个会导致页面重绘,可能衍生出其它的问题。
4、Fragment嵌套BUG之一:被继承的setRetainInstance
Fragments可以设置成保持状态。比如,当屏幕旋转导致Activity销毁和重启时,可以不用重新创建Fragment。
问题: 嵌套的Fragment会继承宿主Fragment的retain instance状态。
原因: 不明
解决: 尚无解决方案。
这个看起来是个很小的点,但是却可能产生很大的问题。虽然个人倾向于让所有fragments重新创建来保证其状态不出错(尤其是有复杂View的场景下),但是如果遇到不存在或简单View的场景是,比如网络请求或者多个组件调用,可能会设置一个回调监听器,而这个监听器是不需要重复创建的。上面所说的这种Fragment如果被嵌套在一个需要重新创建的Fragment里面,由于setRetainInstance 的继承性,会导致这个Fragment也跟着被重新创建。我的解决方式是使用静态实例和弱引用来持有这个Fragment,保证其不需要重新创建,有点坑。。。
5、Fragment嵌套BUG之一:错乱的onActivityResult传递
这是最让人头疼的问题了,而且我们会经常遇到,比如在嵌套的Fragment里面启动Activity。
问题: onActivityResult回调不会走到嵌套的Fragment里面。
原因: Support Library(V4)会修改了requestCode,使其中包含了一个Fragment 16位的索引值。这个索引值是与FragmentManager相关联的,Activity会根据这个索引值在自身的FragmentManager里面搜索Fragment来分发onActivityResult,但是只能搜寻到宿主Fragment,而宿主Fragment却不会向其内部嵌套的Fragment分发。这样就导致嵌套的Fragment永远收不到onActivityResult回调。
解决: 宿主Fragment向其内部嵌套的Fragment发送onActivityResult回调。
补充: 使用系统自带的Fragment不会出现这种问题,谷歌还是很牛逼的哈!
测试源码仓库:https://github.com/BurntBrunch/android-fragment-bugs
结束,谢谢观赏!
Android 多个Fragment嵌套导致的三大BUG的更多相关文章
- Android 中关于Fragment嵌套Fragment的问题
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5802146.html 问题描述: 在项目中Activity A中嵌套Fragment B,Fragment ...
- android开发 Fragment嵌套调用常见错误
在activity中有时须要嵌套调用fragment,但嵌套调用往往带来视图的显示与预期的不一样或是fragment的切换有问题.在使用时要注意几点: 1.fragment中嵌套fragment,子f ...
- 浅谈Android Fragment嵌套使用存在的一些BUG以及解决方法
时间 2014-03-18 18:00:55 eoe博客 原文 http://my.eoe.cn/916054/archive/24053.html 主题 安卓开发 自从Android3.0引入了F ...
- android fragment嵌套fragment出现的问题:no activity
package com.example.fragmentNavigation2.fragment; import android.content.Context; import android.os. ...
- Android Activity和Fragment的转场动画
Android Activity和Fragment的转场动画 Activity转场动画 Activity的转场动画是通过overridePendingTransition(int enterAnim, ...
- 【Android】保存Fragment切换状态
前言 一般频繁切换Fragment会导致频繁的释放和创建,如果Fragment比较臃肿体验就非常不好了,这里分享一个方法. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.c ...
- 两层Fragment嵌套,外层Fragment切换时内层Fragment不显示内容
尊重他人劳动成果,转载请说明出处:http://blog.csdn.net/bingospunky/article/details/46847269 需求 在搭界面有这么样一个需求:须要两层的Frag ...
- Android开发:碎片Fragment完全解析fragment_main.xml/activity_main.xml
Android开发:碎片Fragment完全解析 为了让界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像 Activi ...
- 两层fragment嵌套时出现空白,(收藏别人的)
完美解决 两层Fragment,内层空白 转载:http://blog.csdn.net/bingospunky/article/details/51352400 目录(?)[+] 前言 两层Frag ...
随机推荐
- 洛谷—— P1162 填涂颜色
https://www.luogu.org/problem/show?pid=1162 题目描述 由数字0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向.现要求把闭 ...
- 洛谷 P1571 眼红的Medusa
P1571 眼红的Medusa 题目描述 虽然Miss Medusa到了北京,领了科技创新奖,但是他还是觉得不满意.原因是,他发现很多人都和他一样获了科技创新奖,特别是其中的某些人,还获得了另一个奖项 ...
- ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第六篇:拦截器
摘要 本文将对“MVC公告发布系统”的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法. 一个小难题 我们继续完善“MVC公告发布系统”, ...
- 防止 Chrome 屏蔽 非官方 扩展程序 教程(一)
说明 Google Chrome,又称 Google 浏览器,是一个由 Google(谷歌)公司开发的网页浏览器.该浏览器是基于其它开源软件所撰写.包含 WebKit,目标是提升稳定性.速度和安全性. ...
- iOS之StatusBar详解
随便打开手机上的主流APP,我们不难发现它们的状态栏都是跟导航栏保持一致的背景颜色,如下图的微信和instagram: WECHAT.PNG INS.PNG 那么今天我们就来说一下StatusBar这 ...
- Instruction-Set Support for Invocation of VMM-Configured Services without VMM Intervention
A processing core comprising instruction execution logic circuitry and register space. The register ...
- [Nuxt] Load Data from APIs with Nuxt and Vuex
In a server-rendered application, if you attempt to load data before the page renders and the data f ...
- [Angular] Angular Advanced Features - ng-template , ng-container, ngTemplateOutlet
Previously we have tab-panel template defined like this: <ul class="tab-panel-buttons" ...
- 与Eclipse关于"Call Hierarchy"和"Find Reference"功能比较
"Call Hierarchy"功能比较 Eclipse的"Call Hierarchy"可以查看一个Java方法或类成员变量的调用树(caller和calle ...
- 如何调试Javascript代码
转自原文如何调试Javascript代码 目前,常用的浏览器IE.Chrome.Firefox都有相应的脚本调试功能.作为我们.NET 阵营,学会如何在IE中调试JS就足够了,在掌握了IE中的调试方法 ...