微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CoordinatorLayout 中的 ViewPager用于粘性标题导致滚动中断

如何解决CoordinatorLayout 中的 ViewPager用于粘性标题导致滚动中断

在此处演示问题的测试应用:https://github.com/jstubing/ViewPagerTest

我使用 CoordinatorLayout/AppBarLayout 组合在可滚动页面中实现粘性标题。在页面的最底部一个 ViewPager2。当我滑动到新的 ViewPager 页面时,内容会异步加载并在 ViewPager 中填充 RecyclerView。这一切都很好。

当我滑动到新的 ViewPager 页面时出现问题。此时,内容加载并呈现良好,但我不再能够在 ViewPager 之外启动滚动。换句话说,在“UPPER PAGE CONTENT”部分(请参阅 XML)中上下滑动没有任何作用。

但是,在 ViewPager 中上下滚动确实有效。如果我在 ViewPager 中向上或向下滚动,或者甚至只是点击 ViewPager 一次,它都会修复所有内容,并且我再次能够从 ViewPager 外部启动滚动。

我尝试切换到原来的 ViewPager 而不是 ViewPager2,它确实更可靠,但问题仍然经常发生。

有什么想法可以解决这个问题吗?最终,我只想能够在 ViewPager 页面之间滑动并使整个活动保持可滚动。我很困惑为什么我首先失去了滚动能力,为什么点击 ViewPager 可以修复它。

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:elevation="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/background"
            app:elevation="0dp">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="32dp"
                app:layout_scrollFlags="scroll">

                <!-- UPPER PAGE CONTENT -->

            </androidx.constraintlayout.widget.ConstraintLayout>

            <!-- Sticky header -->
            <include
                android:id="@+id/sticky_header"
                layout="@layout/sticky_header"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </com.google.android.material.appbar.AppBarLayout>

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/events_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

解决方法

当我滑动到新的 ViewPager 页面时出现问题。在这 点,内容加载并呈现良好,但我不再能够 在 ViewPager 之外启动滚动。

我再次能够从 ViewPager 外部启动滚动。

因此,问题现在仅限于 ViewPager。很可能是因为 ViewPager2 支持通过其内部 RecyclerView 嵌套滚动(我不是指页面的 RecyclerView,而是使 ViewPager 在内部起作用的那个。

所以,首先我们需要禁用 ViewPager2 的嵌套滚动:

科特林:

viewPager.children.find { it is RecyclerView }?.let {
        (it as RecyclerView).isNestedScrollingEnabled = false
}

Java:

for (int i = 0; i < viewPager.getChildCount(); i++) {
    View child = viewPager.getChildAt(i);
    if (child instanceof RecyclerView) 
        child.setNestedScrollingEnabled(false);
}

我们不能完全禁用嵌套滚动,因为这会严重影响外部滚动,因此,我们可以通过包装 NestedScrollViewViewPager 进行操作:

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/events_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent />

</androidx.core.widget.NestedScrollView>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。