使用RecyclerView + ViewPager 的两个大坑!
来源:互联网 发布:淘宝网店授权书模板 编辑:程序博客网 时间:2024/06/05 01:51
问题
在RecyclerView中使用ViewPager时,会出现两个诡异的bug:
- RecyclerView滚动上去,直至ViewPager看不见,再滚动下来,ViewPager下一次切换没有动画
- 当ViewPage滚动到一半的时候,RecyclerView滚动上去,再滚动下来,ViewPager会卡在一半
这两个bug只能用两个字形容:大坑!
问题1:原因
ViewPager里有一个私有变量mFirstLayout,它是表示是不是第一次显示布局,如果是true,则使用无动画的方式显示当前item,如果是false,则使用动画方式显示当前item。
看源码
void setCurrentItemInternal(int item, boolean smoothScroll, boolean always, int velocity) { ... if (mFirstLayout) { // We don't have any idea how big we are yet and shouldn't have any pages either. // Just set things up and let the pending layout handle things. mCurItem = item; if (dispatchSelected) { dispatchOnPageSelected(item); } requestLayout(); } else { populate(item); scrollToItem(item, smoothScroll, velocity, dispatchSelected); ...}
当ViewPager滚动上去后,因为RecyclerView的回收机制,ViewPager会走onDetachFromWindow,当再次滚动下来时,ViewPager会走onAttachedToWindow,而问题就出在onAttachToWindow。
看源码:
@Overrideprotected void onAttachedToWindow() { super.onAttachedToWindow(); mFirstLayout = true;}
原来如此,在onAttachedToWindow中,mFirstLayout被重置为true,所以下一次滚动就没有动画。
问题1:解决方法
重写onAttachedToWindow方法,把mFirstLayout再重置成false,因为mFirstLayout是private变量,我们不能直接访问,所以只能反射了。
@Overrideprotected void onAttachedToWindow() { super.onAttachedToWindow(); try { Field mFirstLayout = ViewPager.class.getDeclaredField("mFirstLayout"); mFirstLayout.setAccessible(true); mFirstLayout.set(this, false); getAdapter().notifyDataSetChanged(); setCurrentItem(getCurrentItem()); } catch (Exception e) { e.printStackTrace(); }}
问题2:原因
直接来看ViewPager的onDetachFromWindow方法
@Overrideprotected void onDetachedFromWindow() { removeCallbacks(mEndScrollRunnable); // To be on the safe side, abort the scroller if ((mScroller != null) && !mScroller.isFinished()) { mScroller.abortAnimation(); } super.onDetachedFromWindow();}
尼玛,直接把动画强行停掉了。
问题2:解决方法
想来想去,没什么好办法,只能想办法保护了
@Overrideprotected void onDetachedFromWindow() { if (hasActivityDestroy) { super.onDetachedFromWindow(); }}public void setHasDestroy(boolean hasDestroy) { hasActivityDestroy= hasDestroy;}
当activitydestroy的时候,给自定义ViewPager一个标志位hasActivityDestroy,只有hasActivityDestroy为true的时候,才调用父类的super.onDetachedFromWindow();
总结
这两个bug看了我好久啊,真是个大坑。。。
阅读全文
8 0
- 使用RecyclerView + ViewPager 的两个大坑!
- 使用RecyclerView + ViewPager 实现轮播广告的两个Bug
- TabLayout与RecyclerView的联合使用(不使用ViewPager)
- Espresso 自动化测试(十二) -recyclerView 以及 viewPager的使用
- RecyclerView中使用无限轮播ViewPager的问题
- AFNetWorking框架使用的“两个大坑”——修改请求方式和响应方式
- AFNetWorking框架使用的“两个大坑”——修改请求方式和响应方式
- 使用缓存cache 的大坑
- Acache使用过程的大坑
- ViewPager + RecyclerView的显示问题
- iOS数组和字典的使用----大坑
- Swift 使用 NSClassFromString 遇到的大坑
- RecyclerView+RecyclerView.Adapter+RecyclerView.ViewHolder的使用
- RecyclerView遇到的两个bug
- Android : ViewPager+RecyclerView的联动效果
- 自定义RecyclerView实现垂直滑动的ViewPager
- RecyclerView复用ViewPager出现的问题
- 基于ViewPager+Recyclerview实现的CalendarView视图
- bzoj 1399 坑
- 中缀和后缀表达式之间的转换
- hive distinct groupby等实现原理
- 组件
- WPF仿QQ聊天框表情文字混排实现
- 使用RecyclerView + ViewPager 的两个大坑!
- nodejs异步I/O和事件循环
- ant使用教程-svn篇
- AndroidManifest配置之uses-feature
- Flutter实战一Flutter聊天应用(二)
- HDU 2827 The Evaluation of Determinant 题解
- Python生成器
- python requests 高级用法 -- 包括SSL 证书错误的解决方案
- 功能强大的最新HTML5特效实例