关于RecyclerView嵌套ViewPager的卡钝和动画失效问题 问题 在RecyclerView中使用ViewPager时, 会出现两个常见的bug: 问题 Bug 1 RecyclerView滚动上去, 直至ViewPager看不见, 再滚动下来, ViewPager下一次切换
关于RecyclerView嵌套ViewPager的卡钝和动画失效问题
问题
在RecyclerView中使用ViewPager时, 会出现两个常见的bug:
问题
Bug
1
RecyclerView滚动上去, 直至ViewPager看不见, 再滚动下来, ViewPager下一次切换没有动画
2
ViewPager滚动到一半的时候, RecyclerView滚动上去, 再滚动下来, ViewPager会卡在一半
原因
- ViewPager里有一个私有变量mFirstLayout, 它是表示是不是第一次显示布局, 如果是true, 则使用无动画的方式显示当前item, 如果是false, 则使用动画方式显示当前item
- 当ViewPager滚动上去后, 因为RecyclerView的回收机制, ViewPager会走onDetachFromWindow, 当再次滚动下来时, ViewPager会走onAttachedToWindow, 而问题就出在onAttachToWindow.
解决方案
重写onAttachedToWindow fix ViewPager滚动到一半的时候, RecyclerView滚动上去, 再滚动下来, ViewPager会卡在一半
- Java
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (isLayout && getAdapter() != null && getAdapter().getCount() > 0) {//isLayout是记录是否已经布局到界面的全局变量
try {
//fix 使用RecyclerView + ViewPager bug
Field mScroller = ViewPager.class.getDeclaredField("mFirstLayout");
mScroller.setAccessible(true);
mScroller.set(this, false);
} catch (Exception e) {
e.printStackTrace();
}
}
start();
}
- Kotlin
super.onAttachedToWindow()
if (_isLayout && adapter != null && adapter!!.count > 0) {
try {
//fix 使用RecyclerView + ViewPager bug
val mScroller = ViewPager::class.java.getDeclaredField("mFirstLayout")
mScroller.isAccessible = true
mScroller[this] = false
} catch (e: Exception) {
e.printStackTrace()
}
}
start()
}
重写onDetachedFromWindow fix RecyclerView滚动上去, 直至ViewPager看不见, 再滚动下来, ViewPager下一次切换没有动画
- Java
protected void onDetachedFromWindow() {
//fix 使用RecyclerView + ViewPager bug
if (((Activity) getContext()).isFinishing()) {
super.onDetachedFromWindow();
}
}
- Kotlin
//fix 使用RecyclerView + ViewPager bug
if ((context as Activity).isFinishing) {
super.onDetachedFromWindow()
}
}