曾几何时遇到的bug(viewpager+fragment)

最近写项目的时候遇到了几个奇怪的bug,好在都解决了,现在记录下来(好记性不如烂笔头)

1 tabs + viewpager+fragment

      上面是重写scrollview的tab, 下面是viewpager, viewpager里面用的是fragemnt, 这是一种很常见的场景吧,以前写的时候是没有bug的,但是这次却出现了,调了我几个小时。 现在的需求是上面的tab可以动态的添加和删除,然后下面viewpager里面的fragemnt内容要动态的改变,bug好像是(记不清了)明明参数已经发生改变,但是fragment内容还是一样的,开始的时候我以为是我参数传的不对,经过一遍又一遍的测试后,我开始怀疑是我用的api不对,或者是google的bug, 接着 我将fragment的hashcode打印出来,结果发现: 明明viewpager适配器的数据改变了,但是fragemnt的hashcode没有发生变化,也就是fragemnt 还是原来的! 接着@度娘后发现是我的适配器写的不对,viewpager的适配器要继承FragmentStatePagerAdapter! FragmentPagerAdapter只适合viewpagerfragment不变的情况。

  资料:http://blog.sina.com.cn/s/blog_6400e5c50101l1ri.html

       http://blog.csdn.net/devilkin64/article/details/39379143

 

2 drawerlayer + fragment + viewpager+fragment

     场景是,左边的drawerlayer 有几个选项卡,每点一个tab,切换内容区域的fragemnt, 开始的时候嫌麻烦用的replace,其中有个fragment里面用的是viewpager, viewpager的适配器是fragmentStatePagerAdapter,然而第一次显示的时候木有问题,然而当切换别的fragment第二次切回来就崩掉了,log日志

java.lang.IllegalStateException: Fragment ShopFragmentGoodsList{43547aa8} is not currently in the FragmentManager
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.saveFragmentInstanceState(FragmentManager.java:607)
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.support.v4.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:136)
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:873)
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2826)
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
11-14 22:39:08.933 24824-24824/com.tubban.tubbanBC E/AndroidRuntime: at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)

出现这个异常的原因很多,我这为了不影响其他模块的代码,决定把我这的replace方法替换成add_show_hide的用法, 我用的add是add(Fragment, Sring),结果界面的fragemnt一直不显示(以前一直用的replace, 我也知道add的用法,但是木有用过add,  我用add方法的时候是直接打add然后看感知出来的函数原型, 看到感知的参数有两个,所以我用的这个函数原型), 后来又是一番死去活来的找bug, 大概用了1个下午吧(可怕),最终发现add的函数原型有三个参数的add(int, fragment, string), 研究了一下源码,发现两个参数的add默认第一个参数为0(为毛我会花1下午呢,度娘给握的资料基本木有给函数原型,所以我没有想到是我api用错了, 囧 -.-!!, 果然要学好英文去读google文档比较好么)。 用add(int, fragment, string)成功的解决了我的问题,不过可惜了我一下午的青春啊!

3  tabs + viewpager +fragment

  底下是按钮, 上面是viewpager, viewpager里面放的fragemnt, 总之是一种很常见的用法啦,这么常见为毛我会出bug呢? 

  bug描述: 按了tab后fragment不显示内容!?

  由于产品经理要求按底下的tab后viewpager不要出现滑动的动画,所以我用了ViewPager.setCurrentItem(int, boolean)方法,不过本来这么用是不会有什么问题的,一来是我项目里面fragment用了一些优化方案,比如onCreateView()方法里面用了if (convertView == null) {createView}  return convertView,(优化的方案以后有机会再写,这里就不详谈了)。我的fragment都没有访问网络的操作,所以fragment切换过来的时候并没有更新界面(如果有网络请求,然后网络请求的数据展示在界面上就不会出现这个bug),发现这个问题后,我就试着调用convertview.invalidate, convertview.postInvalidate,等等,结果第一次还是不显示,但是第二次切过来就显示了, 好蛋疼哦, 后来我就在onCreateView加了一些处理, 在出现这个bug的地方去掉优化方案,其实也就是加个判断啦(if (!optimize || convertView == null)), optimize 默认是true, 这样修改后也不会影响其他的代码,如果由于优化而出了bug, 调setOptimize(false)便是, 不过我最后还是采用了另外一种解决方案, 毕竟不想牺牲优化, 一来还是调用convertView.invalidate(), 然后初始化viewpager的时候还要调用viewpager.setoffScreePageLimit(4)(我有4个tab)方法。 总之这个bug解决了, 不过我觉得这个bug遇到的概率还是很小的(ps偏偏被我遇到了).

....(待续)

posted @ 2015-11-14 23:10  章炎  阅读(462)  评论(0编辑  收藏  举报