Recyclerview with scrolling background

你说的曾经没有我的故事 提交于 2019-12-06 03:38:39

问题


I'm trying to create a RecyclerView with scrolling background, like the one shown below. The idea is, as I scroll up/down the viewholders, the background (light-green) image should also move up/down in sync. Any clue as to how to accomplish this?

Here is my basic RecyclerView configuration

<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/item_margin"
android:clipToPadding="false"
android:background="@drawable/ic_light_green_image"/>

回答1:


I had the same use-case -- scrolling a list of cards that lies above the app bar along the Z axis, just like Google Play Music. It's actually pretty simple, but the documentation for RecyclerView#computeVerticalScrollOffset() is completely misleading. It doesn't calculate the scrollbar thumb's offset, instead it calculates by how much the RecyclerView itself has scrolled (which is exactly what we need here).

mPostList.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        int scrollY = mPostList.computeVerticalScrollOffset();
        // mAppBarBg corresponds to your light green background view
        mAppBarBg.setTranslationY(-scrollY);
        // I also have a drop shadow on the Toolbar, this removes the
        // shadow when the list is scrolled to the top
        mToolbarCard.setCardElevation(scrollY <= 0 ? 0 : toolbarElevation);
    }
});

My layout looks like this, if it helps:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- this corresponds to your light green background -->
    <FrameLayout
        android:id="@+id/app_bar_bg"
        android:layout_width="match_parent"
        android:layout_height="@dimen/toolbar_container_height"
        android:background="@color/primary" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!-- CardView adds a drop shadow to the Toolbar -->    
        <android.support.v7.widget.CardView
            android:id="@+id/toolbar_card"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardCornerRadius="0dp">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/post_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:scrollbarStyle="outsideOverlay"
            android:scrollbars="vertical" />

    </LinearLayout>

</FrameLayout>

Hope this helps!




回答2:


I probably wouldn't use the background of the RecyclerView for the actual thing that moves. Maybe don't put a background on the RecyclerView and instead of a different view that is behind the RecyclerView that actually moves. Then you could override onDraw or onLayout on the RecyclerView and update the position of your background to wherever you want it to be relative to the scroll percentage of the RecyclerView.

Something like this... XML:

<RelativeLayout ...>
    <SomeBackgroundView id="backgroundView" ...>
    <MyRecyclerView ...>
</RelativeLayout>

Code:

class MyRecyclerView extends RecyclerView {
    protected int mLastScroll = Integer.MAX_VALUE;
    protected ScrollChangedListener mScrollChangedListener;

    // ...

    @Override
    void onDraw(Canvas c) {
        int scrollY = getScrollY();
        if (scrollY != mLastScroll) {
            mLastScroll = scrollY;
            if (mScrollChangedListener!= null)
                mScrollChangedListener.onScrollChanged(scrollY);
        }

        super.onDraw(c);
    }

    public void setScrollChangedListener(ScrollChangedListener listener) {
        mScrollChangedListener = listener;
    }

    public interface ScrollChangedListener {
        void onScrollChanged(int newScroll);
    }
}

class SomeActivity extends Activity implements ScrollChangedListener {
    // ... 

    @Override
    void onScrollChanged(int newScroll) {
        // Set the background view's position based on newScroll
    }

}


来源:https://stackoverflow.com/questions/29449329/recyclerview-with-scrolling-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!