bgogetap / StickyHeaders

Easily add Sticky Headers to your RecyclerView
Apache License 2.0
521 stars 88 forks source link

StickyHeaders with coordinatorlayout and appbar has a strange behaviour #31

Closed andreborud closed 7 years ago

andreborud commented 7 years ago

Nice work! This is so far the best StickyHeaders library I've tried.

Found a little bit of a bug though, or I implemented it wrongly. The first sticky header is shown on top of the toolbar and appbar in my coordinator layout. Then while scrolling the sticky header disappears, but the sticky headers the hide behind the toolbar as can be seen in the gif below. Any ideas?

app

This is the layout file I'm using:

<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:id="@+id/root_view"
    xmlns:tools="http://schemas.android.com/tools">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize">

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

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="?attr/actionBarSize"
                android:orientation="vertical"
                app:layout_collapseMode="parallax">

                <fragment
                    android:id="@+id/map"
                    android:name="com.google.android.gms.maps.SupportMapFragment"
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    tools:context="com.mobile.races.RacesActivity"/>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="56dp">

                    <ImageView
                        android:id="@+id/event_country"
                        android:layout_width="32dp"
                        android:layout_height="32dp"
                        android:layout_centerVertical="true"
                        android:layout_marginLeft="24dp"/>

                    <TextView
                        android:id="@+id/event_location"
                        android:layout_centerVertical="true"
                        android:textSize="18sp"
                        android:layout_marginLeft="96dp"
                        android:layout_marginRight="16dp"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"/>

                </RelativeLayout>

                <TextView
                    android:layout_marginLeft="96dp"
                    android:layout_marginRight="16dp"
                    android:layout_marginBottom="24dp"
                    android:textSize="13sp"
                    android:lineSpacingMultiplier="1.2"
                    android:id="@+id/event_description"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>

            </LinearLayout>

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

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

                    <TextView
                        android:id="@+id/header_event_name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:includeFontPadding="false"
                        android:maxLines="1"
                        android:ellipsize="end"
                        android:textStyle="bold"
                        android:textColor="@color/tracTracBlue"
                        android:textSize="17sp" />

                    <TextView
                        android:id="@+id/header_dates_name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:maxLines="1"
                        android:includeFontPadding="false"
                        android:textSize="12sp" />

                </LinearLayout>

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

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

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

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:focusableInTouchMode="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

Putting the recyclerview in its own framlayout makes the stickyheaders work and respect the given space, but the coordinatorlayout scrolling stops to work.

bgogetap commented 7 years ago

Thanks, I'm glad you like it!

Wrap your ReyclerView in a FrameLayout and that should take care of it.

Since CoordinatorLayout manages position of AppBar/etc., it is the full height of your screen. CoordinatorLayout will keep other children under the Toolbar, like you see with the RecyclerView, so if the RecyclerView is wrapped in a FrameLayout, that FrameLayout will be used to hold the sticky headers and should position them right where you want them.

I always forget, but you might have to move your "app:layout_behavior="@string/appbar_scrolling_view_behavior" to the FrameLayout when you do this. Just in case the scrolling isn't working as you expect, try that.

(edit: The reason it's disappearing is because the CoordinatorLayout is changing the z ordering of the Toolbar. So the Toolbar is covering the sticky header, which is technically still stickied to the top--that's my theory at least)

andreborud commented 7 years ago

That worked perfectly! Thanks! 👍