03/22
2013

多个ViewPager引发的Fragment未初始化

本文主要介绍ViewPager FragmentPagerAdapter中Fragment缓存的规则

 

可能需要在一个Activity中显示多个ViewPager,如GridView或ListView中以ViewPager做Item。
在Fragment的onCreateView函数中添加断点,结果发现只有第一个ViewPager的Fragment被初始化了

 

排查发现在FragmentPagerAdapter中的instantiateItem函数中FragmentManager以container的id加fragment的position为标记。导致第一个ViewPager的position初始化后进了缓存,第二个ViewPager的position1就直接从缓存中获取数据,查看FragmentPagerAdapter源码如下:

instantiateItemmakeFragmentName
从上红圈标记的地方可以看出查找Fragment的规则,其中container.getId为ViewPager父View的id,position为fragment的位置。
针对上面的makeFragmentName规则,我们有两种解决方法:
1、自己复制FragmentPagerAdapter中的内容,重写一个PagerAdapter,修改其中的makeFragmentname规则,推荐使用此种方法。
2、改变上面container.getId,即ViewPager父View的idcontainerId。不过这种方式只是用于ViewPager较少的情况,否则复制很恶心的。。。
参考:https://groups.google.com/forum/?fromgroups=#!topic/android-developers/cKdvKyneHYY

 

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

15 thoughts on “多个ViewPager引发的Fragment未初始化

  1. Android 4.0.4 / Ice Cream Sandwich MR1 / API 15
    Baseband Version: S890.W12.22.SP.V5.P11, 2012/10/10 16:18
    Build Number: Lenovo S890_S134_130619
    Linux Kernel Version: 3.0.13
    Http User Agent: Dalvik/1.6.0 (Linux; U; Android 4.0.4; Lenovo S890 Build/IMM76D)

  2. 楼主楼主,我的activity里面有多个fragment,每个fragment中有一个viewpage,当默认初始化第一个fragment时第二个第三个fragment里的viewpage中就没有内容,viewpage中的Gridview没有显示出来

  3. 楼主,我现在用的是viewpager+fragment,而fragment有的内嵌listview,有的是gridview,第一次加载进入时,第一页和第二页是listview的,第三页开始fragment的内容是gridview,当翻页第一页进入第二页时,系统会去默加载第三页的数据,而这时,第二页就会产生黑屏的现象,必须触摸下屏幕才正常显示,这是什么原因呢,就首次会这情况,那一次过了,来回翻页都很正常。

    • 我用的场景几乎跟你一样甚至更复杂,没碰到这种问题,应该是你代码的问题,可以注释掉所有的逻辑代码试试。
      至于你说的viewpager的缓存默认加载第三页数据,你可以用viewPager.setOffscreenPageLimit(0)去掉这个特性,不过不建议这样做。

        • 据我了解,这个viewpager是不支持的。预先初始化也不会太耗性能,你可以设置一个变量,若未加载过预先初始化不执行就可以了啊

        • 预先初始化倒不是大问题,问题是加载过的 如果不设置setOffscreenPageLimit,那么再次回到此碎片时除了onCreate之外多会重复执行,这给程序处理带来了太多的不便。相信Google设计成这样有他的目的,但是现在就是不知道目的是啥?

        • 是的,你说的问题确实存在,我曾经也纠结许久找不到解决方法。后来发现setOffscreenPageLimit的性能也没有那么差(是我fragment初始化写的代码性能不好),以后就一直在viewpager设置adapter时就setOffscreenPageLimit为adapter的大小。

        • 我试过大概9个fragment的样子,每个fragment里面只有一个listview外加几个textview,布局并不复杂。对了初始化时setOffscreenPageLimit设置成9和不设置,发现进入页面时间两者有比较明显的差别啊。还是那句话我觉得Google的这个机制是有别的目的的,但是现在想晓得他为什么这样做

        • 你把除了布局加载外的代码全部注释掉看看,感觉只是加载布局的话,即便是9个fragment也不会很慢。fragment加载是并发的