FragmentPagerAdapter与FragmentStatePagerAdapter区别?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jason_Lewis/article/details/79481564

简单记录下两者的区别
FragmentPagerAdapter对于生成的没一个Fragment都会保存在内存当中,适用于页面内容相对固定,数量也较少的情况。对于不需要的fragment,FragmentPagerAdapter会调用事务的detach(Fragment)方法,而不是remove(Fragment)方法,所以FragmentPagerAdapter只是销毁了fragment的视图,但仍将fragment实例保存在FragmentManager中。因此,FragmentPagerAdapter创建的fragment永远不会被销毁。

重写的方法(转):
1. getItem()
①该类中新增的一个虚函数。函数的目的为生成新的 Fragment 对象。重载该函数时需要注意这一点。在需要时,该函数将被 instantiateItem() 所调用。
②如果需要向 Fragment 对象传递相对静态的数据时,我们一般通过 Fragment.setArguments() 来进行,这部分代码应当放到 getItem()。它们只会在新生成 Fragment 对象时执行一遍。
③如果需要在生成 Fragment 对象后,将数据集里面一些动态的数据传递给该 Fragment,那么,这部分代码不适合放到 getItem() 中。因为当数据集发生变化时,往往对应的 Fragment 已经生成,如果传递数据部分代码放到了 getItem() 中,这部分代码将不会被调用。这也是为什么很多人发现调用 PagerAdapter.notifyDataSetChanged() 后,getItem() 没有被调用的一个原因。
2. instantiateItem()
①函数中判断一下要生成的 Fragment 是否已经生成过了,如果生成过了,就使用旧的,旧的将被 Fragment.attach();如果没有,就调用 getItem() 生成一个新的,新的对象将被 FragmentTransation.add()。
②FragmentPagerAdapter 会将所有生成的 Fragment 对象通过 FragmentManager 保存起来备用,以后需要该 Fragment 时,都会从 FragmentManager 读取,而不会再次调用 getItem() 方法。
③如果需要在生成 Fragment 对象后,将数据集中的一些数据传递给该 Fragment,这部分代码应该放到这个函数的重载里。在我们继承的子类中,重载该函数,并调用 FragmentPagerAdapter.instantiateItem() 取得该函数返回 Fragment 对象,然后,我们该 Fragment 对象中对应的方法,将数据传递过去,然后返回该对象。
④否则,如果将这部分传递数据的代码放到 getItem()中,在 PagerAdapter.notifyDataSetChanged() 后,这部分数据设置代码将不会被调用。
3. destroyItem()
①该函数被调用后,会对 Fragment 进行 FragmentTransaction.detach()。这里不是 remove(),只是 detach(),因此 Fragment 还在 FragmentManager 管理中,Fragment 所占用的资源不会被释放。
FragmentStatePagerAdapter会销毁掉不需要的fragment,释放资源,不会占用大量的内存。事务提交后,FragmentStatePagerAdapter会将fragment从activity的FragmentManager中彻底移除。FragmentStatePagerAdapter类名中的“state”表明:在销毁fragment时,它会将其onSaveInstanceState(Bundle)方法中的Bundle信息保存下来。用户切换回原来的页面后,保存的实例状态可用于恢复生成新的fragment。

重写的方法(转):
1. getItem()
①一个该类中新增的虚函数。
②函数的目的为生成新的 Fragment 对象。
③Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。
④由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。
2. instantiateItem()
①除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。
②FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。
3. destroyItem()
①将 Fragment 移除,即调用 FragmentTransaction.remove(),并释放其资源。

猜你喜欢

转载自blog.csdn.net/Jason_Lewis/article/details/79481564