A Parallax header for your RecyclerView using a CoordinatorLayour Behavior (Android Development)

Sometimes you have to build standard UI things, but for an unexplained reason, noone seems to have built it right before you (except the vendor).

It just happend last week. I am building the Android version of an iOS app, where the main page has a fixed toolbar+header, then a list view with its own collapsing header.
Well as strange as it can be, this UI seems impossible to build using standard Android support library layouts and views: the collapsible header for a listview have to be a collapsing toolbar. But this UI already has a fixed toolbar and other fixed ui elements below it!

So today i’m sharing with you a modern way to create and collapse the header of a RecyclerView using the power of Coordinator Layour behaviors.

This solution is one solution among others. Other open source solutions to display a header view includes using an override of RecyclerView, adding decorators, defining a custom Layout manager, or subscribing to scroll events to manually manage a header layout. They are all outdated and less powerful than this one :) But let make your own idea.

Note that the code demonstrated here is written in Xamarin C# for Android (i love C# too much). But it is easily converted to Java or Kotlin.

The problem that is solved

The architecture of the solution

We simply attach a custom CoordinatorLayout’s behavior to the header view by adding the app:layout_behavior attribute and magically the header will appear above the RecyclerView and will scroll with it !

Note: you can add a second CoordinatorLayout even if you already have one at the root of your layout. It is like a FrameLayout.

Note: it must be a CoordinatorLayout as only the direct childs of a CoordinatorLayout are searched for the attribute “app:layout_behavior”.

What is a custom behavior

Image for post
Image for post

For our solution we will create a Nested Scrolling behavior.

The ParallaxHeaderBehavior behavior

You override only the methods of CoordinatorLayout.Behavior you need, and the CoordinatorLayout will call them when appropriate. They are not well documented except in the java source code of the Android Support Library. You can check https://medium.com/@zoha131/coordinatorlayout-behavior-basic-fd9c10d3c6e3 (page from which i borrow the above picture) for some explanations.

So for this custom behavior, we simply:

  • override OnStartNestedScroll to indicate that we wish to receive scroll events for vertical scrolls (otherwise the below methods are not called)
  • overrides OnNestedPreScroll to scroll the header view first (when scrolling down) or scroll the recyclerview first (when scrolling up)
  • override OnNestedFling/OnNestedScroll as flings scroll events are not sent by the CoordinatorLayout. We simply redirect the call to OnNestedPreScroll.
  • override OnLayoutChild in which we add a top padding to the RecyclerView so our header view appears in the blank space left by this padding. Note that i’m also using a SwipeRefreshLayout here, so i moved down the indicator in the same code (with the same padding).

Layout and custom behavior code :

Good luck

Happy coding !
Benjamin Mayrargue, VAPOLIA.

Note: see our fantastic XamSvg and WheelPicker nuget libraries for Xamarin and Forms! https://github.com/softlion/XamSvg-Samples

References

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store