Android – 滚动后无法点击RecyclerView中的项目

我刚刚升级到API 26,并支持库26.0.2。 但是我发现我的RecyclerView项目在滚动后不可点击。 如果你等待一秒钟,它会工作。 但是,如果您立即点击该项目,则不会。 即使RecyclerView没有滚动(例如滚动到顶部)。

当我降级支持库25.4.0一切顺利了。 关键在于我的RecyclerViewCoordinatorLayout ,在SCROLL_FLAG_SCROLL Toolbar上有一个SCROLL_FLAG_SCROLL标志。 如果我不使用这个标志,那么这个问题就会消失。 所以我认为这是支持库26的一个隐藏的行为变化。

我试图在CoordinatorLayout添加focusable="false" ,但仍然没有运气。

有什么办法来禁用这种行为? 因为点击两次触发点击事件真的很烦人。

  <android.support.design.widget.CoordinatorLayout android:id="@+id/coordinateLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/fragmentAppBar" android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" android:background="@null"> <include android:id="@+id/dynamicActionBarHolder" layout="@layout/dynamic_action_bar"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/pullToRefreshMailRecycler" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v7.widget.RecyclerView android:id="@+id/mailRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.v4.widget.SwipeRefreshLayout> </android.support.design.widget.CoordinatorLayout> 

编辑

我认为问题是RecyclerViewscrollState 。 当它停止滚动时,它不会立即更改为SCROLL_STATE_IDLE 。 看着RecyclerView的源代码,我发现有一个ViewFlinger控制滚动状态。 当我扔下来滚动到顶部,它不立即调用setScrollState(SCROLL_STATE_IDLE) ,而是等待一段时间来触发此方法。 我扔得越快,我需要等待的时间就越多。 就像RecyclerView仍在后台滚动一样。 因为scroller.isFinished()RecyclerView停止滚动触摸顶部之后不会立即返回true。 当它在一个CoordinatorLayout时,它可能是RecyclerView的一个bug。

Solutions Collecting From Web of "Android – 滚动后无法点击RecyclerView中的项目"

find了一种强制滚动状态闲置的方法。 等待谷歌来解决这个错误。

 @Override public boolean onInterceptTouchEvent(MotionEvent event) { boolean requestCancelDisallowInterceptTouchEvent = getScrollState() == SCROLL_STATE_SETTLING; boolean consumed = super.onInterceptTouchEvent(event); final int action = event.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: if( requestCancelDisallowInterceptTouchEvent ){ getParent().requestDisallowInterceptTouchEvent(false); // only if it touched the top or the bottom. Thanks to @Sergey's answer. if (!canScrollVertically(-1) || !canScrollVertically(1)) { // stop scroll to enable child view to get the touch event stopScroll(); // do not consume the event return false; } } break; } return consumed; } 

编辑

该问题已在支持库27.0.1中修复。

https://developer.android.com/topic/libraries/support-library/revisions.html#27-0-1

用户滚动后,他们无法点击RecyclerView中的项目。 (AOSP号码66996774)

2017年11月17日更新

有些用户报告说这个问题在支持库27.0.1中没有解决。 问题跟踪器在这里。 https://issuetracker.google.com/issues/66996774

所以你可以select使用这个官方的解决方法。 https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2

或者在这里使用这个。

非常感谢你的回答! 这节省了我很多时间。 对不起,发布这个答案。 我没有足够的评价。

我也注意到这个问题,但作为一个新的Android开发者,我没有意识到这是新的支持库中的一个bug。

我想build议的还是添加这个检查:

 if( requestCancelDisallowInterceptTouchEvent ){ if (!canScrollVertically(-1) || !canScrollVertically(1)) { ... } } 

这将确保RecyclerView实际上被滚动时,我们不会点击任何项目。

据我所知,这是一个预期的行为。 不过,你的回答帮助我解决了这个问题 。