复现
开发过程中遇到一个问题,recyclerView 中快速滑动到尾部时,点击无响应,第二次点击生效。
查找原因
首先想到的就是焦点问题。控件中并无主动获取焦点行为的控件,理应没有这种问题,尝试主动获取焦点,无效。
问题最终放到recyclerView本身,监听recyclerView滑动事件输出log查看recyclerView状态。滑动结束后,recyclerView仍然处于滑动状态,尝试在recyclerView中滑动结束后主动设置状态,当dy为正,并且已经完全显示完成,则设置停止。
if (dy > 0) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int visibleItemCount = linearLayoutManager.getChildCount();
int totalItemCount = linearLayoutManager.getItemCount();
int pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition();
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
if (!recyclerView.canScrollVertically(1)) {
recyclerView.stopScroll();
}
}
}
发现有一定效果,仍然无法完全解决。
由该现象推测,一段时间后,recyclerView状态回归正常。尝试滑动后过一会点击,确实有效,该原因实锤。
搜索引擎检索后查找到有描述和AppBarLayout相关导致。原因是Google在修复滑动时引入的bug,谷歌给出了修复办法。
解决办法
public class FixAppBarLayoutBehavior extends AppBarLayout.Behavior {
public FixAppBarLayoutBehavior() {
super();
}
public FixAppBarLayoutBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,
int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, type);
stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View target, int dx, int dy, int[] consumed, int type) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
stopNestedScrollIfNeeded(dy, child, target, type);
}
private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) {
if (type == ViewCompat.TYPE_NON_TOUCH) {
final int currOffset = getTopAndBottomOffset();
if ((dy < 0 && currOffset == 0)
|| (dy > 0 && currOffset == -child.getTotalScrollRange())) {
ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH);
}
}
}
}
在xml或者代码中使用Behavior即可解决该问题