SwipeRefreshLayout不拦截NestedScrollingChild的MotionEvent

Bry*_*yan 9 android swiperefreshlayout android-touch-event android-nestedscrollview

我使用的是NestedScrollWebView(在很大程度上受到影响NestedScrollView),这可以解决许多已知 问题与使用相关联WebViewCoordinatorLayout.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="enterAlways|scroll|snap">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:titleTextAppearance="@style/TextAppearance.AppCompat.Subhead"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

            <ProgressBar
                android:id="@+id/progressBar"
                android:layout_width="match_parent"
                android:layout_height="2dp"
                android:layout_gravity="bottom"
                android:visibility="gone"
                style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

        </FrameLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <com.example.app.widget.NestedScrollWebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </android.support.v4.widget.SwipeRefreshLayout>

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

这些NestedScrollWebView作品很好用AppBarLayoutenterAlways|scroll|snap滚动标志,但不是很好SwipeRefreshLayout.


我删除了以下行NestedScrollWebView:

setOverScrollMode(WebView.OVER_SCROLL_NEVER);
Run Code Online (Sandbox Code Playgroud)

这样可以确保视图不会显示在滚动指示器上.我想要显示滚动指示符,但即使启用了过度滚动,也不会出现以下情况.


根据我的理解,SwipeRefreshLayout应该拦截导致刷新指示符被拖动的任何触摸事件(基于其实现onInterceptTouchEvent()).SwipeRefreshLayout也拒绝任何requestDisallowInterceptTouchEvent()已启用嵌套滚动的子项; 这是真的NestedScrollWebView.因此,应按以下方式处理这些事件:

如果从中返回true onInterceptTouchEvent(),则之前处理触摸事件的子视图将收到一个ACTION_CANCEL,并且从该点开始的事件将被发送到父 onTouchEvent()方法以进行常规处理.

相反,我看到的行为是SwipeRefreshLayout暗中侦察触摸事件,NestedScrollWebView但它实际上从未拦截它们.事实证明,NestedScrollWebView永远不会收到ACTION_CANCEL触摸事件,即使SwipeRefreshLayout指标被拖下来,它也会继续接收后续事件.

这在以下屏幕截图中进行了演示; 它显示了同时显示的指示器SwipeRefreshLayout以及过滚动指示器WebView.

过度滚动和刷新指示器串联显示

我无法弄清楚为什么会这样.正如我之前提到的,SwipeRefreshLayout应该适用于任何已启用嵌套滚动的视图,但由于某种原因它在这种情况下不起作用.可能是什么问题?


更新

我认为这与NestedScrollWebViewhandle dispatchNestedPre...方法的方式以及它总是将整个方法传递MotionEventsuper.onTouchEvent()方法有关.根据文件:

嵌套的预滚动事件是嵌套滚动事件触摸拦截的触摸.dispatchNestedPreScroll为嵌套滚动操作中的父视图提供了在子视图使用它之前使用部分或全部滚动操作的机会.

现在我必须弄清楚如何NestedScrollWebView正确地重新处理这些方法.

Pra*_*ani 0

希望您能从新发布的接口中得到一些解决方案:

NestedScrollingChild接口:

NestedScrollingParent接口:

谢谢。