Android: pin TabLayout to top of Scrollview


Question: 

I was looking at the twitter app on my phone.

twitter app

You can see that when a user scrolls up, the tabLayout actually just pins itself onto the bottom of the toolbar nicely and does not move at all.

I thought maybe they did it by just putting all of the top part of the app (the profile picture, the profile wallpaper of the bicycle on the grass, the text), into a CollapsingToolBarLayout and AppBarLayout but actually, only the profile wallpaper with the bicycle on the grass is part of the CollapsingToolBarLayout and AppBarLayout as that is the only part that actually collapses. The text part just scrolls up and the tabLayout just pins to the top below the toolbar.

I read the credits on the twitter app and it appears that they used the SlidingTabLayout to achieve their effect. SlidingTabLayout is similar to tabLayout with the latter being supported in the support library.

It looks like a fairly common pattern that is used by mainstream apps nowadays as well -

Google+ app uses it in their profile view on the app:

google+

Facebook Moments uses it in their app:

facebook moments

Any idea how they did all managed to do this?

I'm looking to do something similar to all these apps.

My requirements are to:

  1. Have a collapsingToolBarLayout that collapses when you scroll up
  2. Have a textview underneath the collapsingToolBarLayout that would scroll and "hide" underneath the toolBar when it fully collapses.
  3. Have a tabLayout underneath the textview that would "stick" to the tabLayout when you have scroll the textview under the collapsingToolBarLayout.
  4. Have a recyclerview underneath the tabLayout so that when you click on each tab in the tabLayout, recyclerview will switch between lists of "Tweets", "Photos", "Favourites" etc.

I looked at two other questions that were posted on SO:

Can the tab selection indicator of TabLayout be pinned to the top of the screen while scrolling?. The answer here appears to be changing the behavior of the tabLayout but I doubt changing the behavior would actually generate what the twitter app does. As I mentioned, the tabLayout appears to sit outside the CollapsingToolBarLayout and AppBarLayout and the behavior should only be effective if it is sitting within the CollapsingToolBarLayout and AppBarLayout.

How to pin TabLaout at top of ScrollView?. This question asks something similar to what I asked, but does not give enough detail and has no answers.




3 Answers: 

for those first 3 questions look here (link seems dead) so this wayback machine link. it points to a github demo repo at https://github.com/slidenerd/Android-Design-Support-Library-Demo

As for the 4th you need to create fragments for each tab and load them when they are selected for a simple approach, or you can create one fragment and communicate with it to show specific content when a tab is selected..

EDIT couldn't find an updated link so here are the answers

  1. Use CoordinaterLayout.
  2. Any thing you want to collapse (or hide) with tool bar goes inside collapsingToolBarLayout.
  3. Any thing that stays after collapsed toolBar goes inside of AppBarLayout after CollapsingToolbarLayout.

ex -

<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:background="@android:color/background_light"
    android:fitsSystemWindows="true"
    >

    <android.support.design.widget.AppBarLayout
        android:id="@+id/main.appbar"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true"
        >

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp"
            >

            <ImageView
                android:id="@+id/main.backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                android:src="@drawable/material_flat"
                app:layout_collapseMode="parallax"
                />

            <android.support.v7.widget.Toolbar
                android:id="@+id/main.toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin"
                />
         <!-- ADD ANY THING THAT GETS SCROLLED ALL THE WAY UP WITH TOOLBAR -->
        </android.support.design.widget.CollapsingToolbarLayout>

     <!--- ADD TAB_LAYOUT HERE---> 

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

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

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:lineSpacingExtra="8dp"
            android:text="@string/lorem"
            android:padding="@dimen/activity_horizontal_margin"
            />
    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_margin="@dimen/activity_horizontal_margin"
        android:src="@drawable/ic_comment_24dp"
        app:layout_anchor="@id/main.appbar"
        app:layout_anchorGravity="bottom|right|end"
        />
</android.support.design.widget.CoordinatorLayout>
 

By default there may not be a library that supports that. But you can indeed achieve it with a little bit of programming. Listen to the scrollview events through ViewTreeObserver, and manipulate others. If you are still not sure, let's make a library for it. You make an app and post in github, I will collaborate to make it working.

 

The closest solution to achieve the above mentioned is MaterialViewPager. It's a good starting point, you can fork it and modify for your own preferences, and you can customize it many ways.

 

More Articles


mfc - How do I handle toolbar messages in a dialog box

I am writing a MFC MDI application, which I started with the wizard, with visual studio 2017. In this application I have dialog boxes with toolbars. But when the dialog boxes are shown, the toolbar buttons are not enabled, even though the dialog classes contain handlers for the button IDs.For instan

visual studio - C# Registerhotkey() won't read some keycodes

While trying to create an auto clicker application using a Visual Studio Windows Form that allows you to select the hotkey you want, I stumbled upon a problemWhen a user inputs keys such as ~ or / the hotkey won't work, However, if I put in 0xC0 (for tilde) or 0xDC (for slash) instead of (int)[tilde

mfc - How to make a floating CMFCToolbar nonmovable

First I make my CMFCToolbar permanent withm_wndMyToolBar.SetPermament(TRUE); // it removes the CLOSE Button Now, how can I achieve that the user can not move the permanent CMFCToolbar?I have tried to subclass the CMFCToolbar, but the ON_WM_MOUSEMOVE & ON_WM_NCMOUSEMOVE are never called inside t


java - I want to change the color of Toolbar of the application on scrolling

I have a toolbar that change color on scrolling basicly color is transparent and when scrolling it change color I want to set only one color instead of transparent and let one color be shownI have tried to change color on toolbar xml and display scroling in activitythis my toolbar.xml<?xml versio

visual c++ - OnInitMenuPopup does not init correctly when called from a toolbar button that was a POPUP menu in the App main menu bar

To make a long history short, imagine my main menu is a CMFCMenuBar which menu is defined by:IDR_MAINFRAME MENUBEGIN POPUP "&File" BEGIN MENUITEM "New", ID_FILE_NEW MENUITEM "Open", ID_FILE_OPEN MENUITEM "Save", ID_FILE_SAVE

material design - android lollipop toolbar: how to hide/show the toolbar while scrolling?

I'm using the new toolbar widget introduced in the appcompat / support-v7. I would like to hide/show the toolbar depending on if the user is scrolling up/down the page, just like in the new Google's playstore app or NewsStand app. Is there something built into the toolbar widget for this or should I


wpf - Canvas control is not available in Windows form application?

WPF Canvas control is not available in Windows form application. Am using Visual Studio 2010. Framework 4.0. Is there way to add these controls to VS2010 toolbox?

android - How to get a progress bar under the ActionBar in Material Design?

The Material Design specifications for Progress and activity specifically show in several areas a horizontal progress indicator of only a few pixels (dips) thick below whatever it is we are calling the ActionBar these days (probably Toolbar).However, I don't see any way to actually implement that po

c# - WindowsForm app with wpf windows is not working on other computers

I'm new to WPF and c# programming,i have built a winform app with a database and some wpf forms.wpf forms contain some background images and componentone tab controls.To add wpf forms:i added a wpf user control and modified its code as a window.in that case i m unable to put background images from u

configuration - PhpStorm configure to work remotely

Hi is there a way for PhpStorm to work directly on a remote server? No local files. Because as of the moment PhpStorm has local files wherein it just automatically uploads all files during save on remote.My problem is if someone changes something remotely I need to manually download it first before