You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CoordinatorLayout中双RecyclerView联动滚动异常问题求助

Fixing Synchronous Scrolling for Two RecyclerViews in CoordinatorLayout

Hey there! I see the issue you're facing—your first RecyclerView is scrolling independently while the second one stays put, and you want both to scroll in sync along with the AppBarLayout. Let's break down why this is happening and how to fix it.

Why the Current Setup Isn't Working

Right now, your two RecyclerViews sit inside a RelativeLayout with the appbar_scrolling_view_behavior attached. The first RecyclerView uses wrap_content for height, which lets it scroll on its own, while the second uses match_parent but doesn't sync with the first because they're separate scrollable views. They aren't part of a single scrollable container, so their scroll behaviors are completely independent.

The simplest and most reliable way to get both RecyclerViews to scroll together is to wrap them (along with their header TextViews) in a NestedScrollView. This turns the entire content area into one scrollable unit that works seamlessly with the CoordinatorLayout and AppBarLayout.

Here's your modified layout code:

<android.support.design.widget.CoordinatorLayout 
    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" 
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout 
        android:id="@+id/app_bar_layout" 
        android:layout_width="match_parent" 
        android:layout_height="200dp" 
        android:background="@color/colorThemeDark" 
        android:fitsSystemWindows="true" 
        android:stateListAnimator="@drawable/appbar_always_elevated" 
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout 
            android:id="@+id/collapsing_toolbar_layout" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:fitsSystemWindows="true" 
            app:collapsedTitleGravity="left" 
            app:contentScrim="@color/colorThemeDark" 
            app:expandedTitleGravity="center|bottom" 
            app:expandedTitleTextAppearance="@style/ExpandedAppBar" 
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <de.hdodenhof.circleimageview.CircleImageView 
                android:id="@+id/circleView" 
                android:layout_width="80dp" 
                android:layout_height="80dp" 
                android:layout_centerHorizontal="true" 
                android:layout_gravity="center_vertical|center_horizontal" 
                android:src="@drawable/main_logo" 
                app:layout_collapseMode="none" />

            <android.support.v7.widget.Toolbar 
                android:id="@+id/toolbar" 
                android:layout_width="match_parent" 
                android:layout_height="?android:attr/actionBarSize" 
                android:theme="@style/ThemeOverlay.AppCompat.Light" 
                app:layout_collapseMode="pin" />

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

    <!-- Replace inner RelativeLayout with NestedScrollView -->
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:fillViewport="true">

        <!-- Use LinearLayout to stack content vertically -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="#323642">

            <RelativeLayout 
                android:id="@+id/firstText" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="5dp" 
                android:paddingLeft="10dp">

                <TextView 
                    android:layout_width="match_parent" 
                    android:layout_height="wrap_content" 
                    android:text="What you learn today?" 
                    android:textColor="@color/colorWhite" 
                    android:textStyle="bold" />
            </RelativeLayout>

            <android.support.v7.widget.RecyclerView 
                android:id="@+id/catBoxes" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="5dp" 
                android:paddingLeft="5dp" 
                android:paddingRight="5dp"
                android:nestedScrollingEnabled="false" /> <!-- Disable internal scrolling -->

            <RelativeLayout 
                android:id="@+id/secondText" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="5dp"
                android:paddingLeft="10dp">

                <TextView 
                    android:layout_width="match_parent" 
                    android:layout_height="wrap_content" 
                    android:text="Recommended for you" 
                    android:textColor="@color/colorWhite" 
                    android:textStyle="bold" />
            </RelativeLayout>

            <android.support.v7.widget.RecyclerView 
                android:id="@+id/catMenu" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="5dp"
                android:nestedScrollingEnabled="false" /> <!-- Disable internal scrolling -->

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

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

Key Changes Explained:

  • NestedScrollView: Acts as the single scrollable container that syncs with the AppBarLayout. android:fillViewport="true" ensures it takes up the full screen height.
  • LinearLayout: Replaces the inner RelativeLayout to stack all content (headers + RecyclerViews) vertically in a continuous flow.
  • android:nestedScrollingEnabled="false": Added to both RecyclerViews to disable their internal scrolling behavior—this lets the NestedScrollView handle all scrolling, ensuring both lists move together.
  • RecyclerView Height: Changed to wrap_content so the NestedScrollView can correctly measure the total height of each list.

Solution 2: Sync Scroll Events Programmatically (Alternative)

If you prefer not to use NestedScrollView, you can manually sync the scroll positions of the two RecyclerViews by adding scroll listeners. Here's how:

In your Activity/Fragment:

RecyclerView catBoxes = findViewById(R.id.catBoxes);
RecyclerView catMenu = findViewById(R.id.catMenu);

// Sync catMenu with catBoxes scrolling
catBoxes.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        catMenu.scrollBy(dx, dy);
    }
});

// Optional: Sync catBoxes with catMenu scrolling if needed
catMenu.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        catBoxes.scrollBy(dx, dy);
    }
});

Note: This approach might have minor performance issues or sync lag compared to the NestedScrollView method, so it's better to use Solution 1 unless you have specific reasons to avoid NestedScrollView.

内容的提问来源于stack exchange,提问作者user9779588

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:06:43