在AppBarLayout折叠之前,防止RecyclerView在AppBarLayout下滚动

问题描述 投票:6回答:3

我正在创建一个带有标题的RecyclerView,当你向上滚动RecyclerView时标题会崩溃。我可以通过下面的布局非常密切地实现这一点,使用透明的AppBarLayoutMyCoolView作为标题。视差效果很好。

但是,如果标题仍然可见并且我扔了RecyclerView,则RV会缓慢滚动到顶部,并且某些项目位于工具栏下,直到RV到达视图的顶部。我一直在玩scrollFlags,但没有取得理想的结果。有关如何改善投掷体验的任何建议,以免物品被剪裁?

观看视频,观看它的畏缩--- https://www.dropbox.com/s/jppd6m7zo41k23z/20160609_151309.mp4?dl=0

<android.support.design.widget.CoordinatorLayout>

     <android.support.design.widget.AppBarLayout
         android:background="#00000000">

         <android.support.design.widget.CollapsingToolbarLayout
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

             <com.android.myapp.MyCoolView
                app:layout_collapseMode="parallax"/>

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

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

    <android.support.v7.widget.RecyclerView/>

</android.support.design.widget.CoordinatorLayout>
android android-support-library android-coordinatorlayout android-design-library android-appbarlayout
3个回答
5
投票

可能的解决方案(未经测试)。将OnOffsetChangedListener添加到AppBarLayout,并记下偏移值。首先,声明此字段:

private boolean shouldScroll = false;

然后,onCreate:

AppBarLayout appbar = findViewById(...);
appbar.addOnOffsetChangedListener(new OnOffsetChangedListener() {
    @Override
    void onOffsetChanged(AppBarLayout appbar, int offset) {
        // Allow recycler scrolling only if we started collapsing.
        this.shouldScroll = offset != 0;
    }
});

现在,向RecyclerView添加一个滚动侦听器。每当它尝试滚动时,如果AppBarLayout仍然展开,则还原滚动:

RecyclerView recycler = findViewById(...);
recycler.addOnScrollListener(new OnScrollListener() {
    @Override
    void onScrolled(RecyclerView recycler, int dx, int dy) {
        // If AppBar is fully expanded, revert the scroll.
        if (!shouldScroll) {
            recycler.scrollTo(0,0);
        }
    }
});

这可能需要一些调整。我看到两个问题:

  • 如果scrollTo()调用onScrolled(),则可能发生堆栈溢出。可以使用布尔值或通过删除/添加滚动侦听器来解决
  • 可能你想要防止滚动不仅在AppBarLayout完全展开时,而且更常见的是当AppBarLayout没有折叠时。这意味着你不必检查offset != 0,而是检查offset == appBarLayout.getTotalScrollRange()。我认为。

0
投票

也许你可以像这样在你的RecylerView中添加layout_behavior =“@ string / appbar_scrolling_view_behavior”。

<android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" />

0
投票

在FrameLayout中包装RecyclerView解决了这个问题。

您还需要将appbar_scrolling_view_behavior从RecyclerView移动到FrameLayout,以便它正确定位在AppBarLayout下方。

<android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.AppBarLayout
        android:background="#00000000">

        <android.support.design.widget.CollapsingToolbarLayout
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <com.android.myapp.MyCoolView
               app:layout_collapseMode="parallax"/>

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

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

    <!-- BEGIN SOLUTION -->
    <!-- the layout behavior needs to be set on the FrameLayout, not the RecyclerView -->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        >

        <!--This RecyclerView MUST be wrapped in a FrameLayout-->
        <!--This prevents the RecyclerView from going behind the AppBarLayout-->
        <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />

    </FrameLayout>
    <!-- END SOLUTION -->

</android.support.design.widget.CoordinatorLayout>
© www.soinside.com 2019 - 2024. All rights reserved.