Android-滚动后无法单击RecyclerView中的项目 [英] Android - the item inside RecyclerView can't be clicked after scroll

查看:54
本文介绍了Android-滚动后无法单击RecyclerView中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚升级到API 26,并支持库26.0.2.但是我发现在滚动后我的RecyclerView项不可单击.如果您稍等片刻,它将起作用.但是,如果您立即单击该项目,则不会.即使RecyclerView根本没有滚动(例如已经滚动到顶部).

I just upgraded to API 26 and support library 26.0.2. But I found that my RecyclerView items is not clickable right after the scrolling. If you wait for a second, it will work. But if you click the item immediately, it won't. Even if the RecyclerView is not scrolling at all(e.g. has scrolled to the top).

当我降级到支持库25.4.0时,一切再次恢复正常. 关键是我的RecyclerViewCoordinatorLayout中,并且在AppBarLayout的我的Toolbar上具有SCROLL_FLAG_SCROLL标志.如果我不使用此标志,则此问题将消失.因此,我认为这是支持库26的隐藏行为更改.

When I downgraded to support library 25.4.0 everything goes fine again. The key point is that my RecyclerView is in a CoordinatorLayout and has a SCROLL_FLAG_SCROLL flag on my Toolbar of the AppBarLayout. If I don't use this flag, then this problem will disappear. So I think it's a hidden behavior change of support library 26.

我尝试将focusable="false"添加到CoordinatorLayout,但仍然没有运气.

I've tried to add focusable="false" to the CoordinatorLayout but still had no luck.

有什么办法可以禁用此行为?因为单击两次触发click事件确实很烦人.

Is there any way to disable this behavior? Because it's really annoying to click twice to trigger the click event.

 <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()在碰到顶部时停止滚动后,scroller.isFinished()不会立即返回true.放在CoordinatorLayout中时,可能是RecyclerView的错误.

I think the problem is the scrollState of the RecyclerView. When it's stopped scrolling, it's not changed to SCROLL_STATE_IDLE immediately. Looking into the source code of RecyclerView, I found there's a ViewFlinger controlling the scroll state. When I fling down to scroll to the top, it's not calling setScrollState(SCROLL_STATE_IDLE) immediately, instead, it wait for a while to trigger this method. The more fast I fling, the more time I need to wait. It just like the RecyclerView is still scrolling in the background. Because the scroller.isFinished() doesn't return true right after the RecyclerView stop scrolling when it touched the top. Maybe it's a bug of the RecyclerView when it's in a CoordinatorLayout.

推荐答案

找到了一种强制滚动状态为空闲的方法. 等待谷歌修复此错误.

Found a way to force the scroll state to be idle. Waiting for google to fix this bug.

@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中修复.

The issue has been fixed in support library 27.0.1.

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

用户滚动后,他们无法在RecyclerView中单击某个项目. (AOSP问题66996774)

After a user scrolls, they cannot click on an item in a RecyclerView. (AOSP issue 66996774)

2017年11月17日更新

Updated on Nov 17, 2017

一些用户报告说,支持库27.0.1中未解决此问题. 问题跟踪器在这里. https://issuetracker.google.com/issues/66996774

Some users reported that this problem is not fixed in support library 27.0.1. The issue tracker is here. https://issuetracker.google.com/issues/66996774

因此,您可以选择使用此官方替代方法. https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2

So you may choose to use this official workaround. https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2

或者在这里使用这个.

这篇关于Android-滚动后无法单击RecyclerView中的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆