SwipeRefreshLayout不拦截NestedScrollingChild的MotionEvent

时间:2017-08-18 16:44:36

标签: android swiperefreshlayout android-nestedscrollview android-touch-event

我正在使用NestedScrollWebView(受NestedScrollView影响很大),这解决了许多与使用WebView相关联的known issues CoordinatorLayout

<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>

NestedScrollWebView适用于AppBarLayoutenterAlways|scroll|snap滚动标记,但与SwipeRefreshLayout不太一样。

我从NestedScrollWebView

中删除了以下行
setOverScrollMode(WebView.OVER_SCROLL_NEVER);

确保视图不会显示在滚动指示符上。我希望覆盖滚动指示符,但即使启用了过度滚动,也不会出现以下情况。

根据我的理解,SwipeRefreshLayout应该拦截导致刷新指示符被拖动的任何触摸事件(基于其onInterceptTouchEvent()的实现)。 SwipeRefreshLayout也拒绝任何已启用嵌套滚动的子项requestDisallowInterceptTouchEvent();这对于NestedScrollWebView是正确的。因此,应在following manner

中处理这些事件
  

如果从onInterceptTouchEvent()返回true,那么子视图就是这样   以前处理触摸事件的人会收到ACTION_CANCEL,和   从那一点开始的事件被发送给父母   通常处理的onTouchEvent()方法。

相反,我看到的行为是SwipeRefreshLayout会对NestedScrollWebView的触摸事件进行监视,但它实际上从未拦截它们。事实证明,NestedScrollWebView永远不会收到ACTION_CANCEL触摸事件,并且即使拖出SwipeRefreshLayout指标,它也会继续接收后续事件。

以下屏幕截图中对此进行了演示;它显示SwipeRefreshLayout的指示符以及同时显示的WebView的滚动指示符。

overscroll and refresh indicator shown in tandem

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

更新

我认为这与NestedScrollWebView处理dispatchNestedPre...方法的方式以及它总是将整个MotionEvent传递给super.onTouchEvent()方法的事实有关。根据{{​​3}}:

  

嵌套的预滚动事件是嵌套滚动事件的触摸   拦截是触摸。 dispatchNestedPreScroll提供了机会   对于嵌套滚动操作中的父视图来消耗一些或   子视图消耗它之前的所有滚动操作。

现在我必须弄清楚如何重新设计NestedScrollWebView来正确处理这些方法。

1 个答案:

答案 0 :(得分:0)

希望您将从新发布的界面中获得一些解决方案:

NestedScrollingChild界面:

NestedScrollingParent界面:

谢谢。