Fragment不得不说的一些事

  • 内容
  • 评论
  • 相关

Activity重创建对Fragment的影响

首先看一段我们在代码中经常出现的片段

乍一看上去还是非常ok的,创建一个Fragment然后添加到布局,可是当我们打开开发者选项中的"不保留应用"然后再回到应用就会发现我们常见的Fragment重叠的问题。

原因:当我们的Activity被系统回收然后再次重建的时候FragmentManager会帮我们重新恢复上次的Fragment的状态,所以我们不应该直接创建Fragment然后添加,而是应该判断Fragment是否已经存在!

正确做法:在添加Fragment之前判断是否存在,如果不存在才添加

FragmentManager为我们保存了那些有关Fragment的信息呢?我们查看一下FragmentState类即可,包括Fragment的可见性、实例等等

PS:我们使用Activity+Fragment是否常用的一个操作就是使用一个下标标记当前显示的是哪一个Fragment,所以对于这个变量我们也需要自己手动保存,如下

在上面的代码中没有使用onRestoreInstanceState的原因是,当Activity被系统回收再重建的调用顺序是onSaveInstanceState->onCreate->onRestoreInstanceState

Fragment与ViewPager的那些事

同样的,我们再看一段代码

首先定义好数据集,然后在Adapter中返回给ViewPager,这样会有问题么?同样打开开发者选项中的"不保留应用"然后返回应用,如果这个时候我们在getItem中添加了日志则会发现,当我们选中已经被加载过的Fragment,这个时候getItem并不会被调用!!!

原因:其中的原理其实和最开始我们提出的一样,FragmentManager为我们保存了已经加载的Fragment以及各种状态,所以我们使用List保存Fragment列表的做法是错的,因为当Activity重建的时候,我们则多创建了几个永远不会被加载到ViewPager的Fragment,并且如果我们的业务依赖了这些Fragment,比如在Activity中调用Fragment的方法,则没有任何效果并可能导致Crash。

我们查看一下FragmentPagerAdapter的源码中的instantiateItem方法

我们可以很容易发现,FragmentPagerAdapter使用了findFragmentByTag方法去获取Fragment是否已经被加载过了,如果没有才会调用getItem。至于tag则是由makeFragmentName方法创建。

PS:既然我们知道了Fragment的tag,那么我们能自己拼接tag然后获取Fragment么?答案是可以的!!!

不过要注意的是,如果Fragment没有加载,可能获取到的为null

参考链接

https://www.jianshu.com/p/3d27ddc952fe

评论

0条评论

发表评论

电子邮件地址不会被公开。