Scrolling with Collapsing Toolbar and Tabs
Asked Answered
A

5

12

I'm trying to make a layout with a CollapsingToolbarLayout which has scroll|exitUntilCollapsed flag, and a TabLayout which has scroll|enterAlways scrollFlag property. Basically I want my toolbar to be pinned and show and hide the tabs while scrolling. I've modified the cheesesquare app from https://github.com/chrisbanes/cheesesquare. Here is my layout xml;

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            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/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

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

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_discuss"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

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

And here is the result;

The tabs are not positioned properly. And they don't care about the enterAlways property.

enter image description here

Acceptable answered 30/9, 2015 at 12:21 Comment(7)
Where do you want to have your TabLayout below your AppBar?Beecher
@BhaveshPatadiya Yes. Below the AppBar.Acceptable
one more clarification, just to simplify - what is the expected scroll behavior? Is it right retelling: At first image is visible in full height, then it is scrolled to Toolbar. And further scroll hides tabs and remains Toolbar?Snowy
@Snowy Yes. Exactly. And scrolling down shows the tabs again.Acceptable
Try to put your TabLayout as direct child of AppBarLayout instead of inside CollapsingToolbarLayout.Balsam
Sorry Syloc, I know you've answered this a few times, but I'm still a little confused on the desired behaviour. Should the tabs be visible when the AppBar is fully expanded, or when the AppBar is fully collapsed? And where do you want the tabs to be when they appear?Erminiaerminie
@Erminiaerminie Let me tell you step by step. Initially; the collapsing toolbar with the image is fully expanded and the tabs are visible. Then while scrolling down the collopsing toolbar image will shrink to the toolbar. (The tabs are still visible). When the collapsing toolbar is fully collopsed, further scroll downs will hide the tabs, but pins the toolbar. And scrolling up will show the tabs again.Acceptable
C
20

Hey this may solve your problem.

just add android:layout_gravity="bottom" to tablayout and android:gravity="top" to toolbar.

enter image description here

Crowell answered 30/1, 2016 at 19:46 Comment(5)
actually its about toolbar margin_bottomIndices
example from link works great, exactly like in this imgDurnan
The link is obsoleteLeaves
@Jimale your given link is a spam link, Remove this link or I will complain against you, you are spreading spam.Almuce
@Pavel This is not my answer, I have edited itArchilochus
K
5
  1. Remove attribute app:layout_behavior="@string/appbar_scrolling_view_behavior" & app:layout_scrollFlags="scroll|enterAlways" from android.support.design.widget.TabLayout and add attribute android:layout_gravity="bottom".

  2. Also set android.support.v7.widget.Toolbar height as 104(Toolbar+TabLayout height) to show both Toolbar and TabLayout during collapsed state.

Here is an working example:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:titleEnabled="false">

            <ImageView
                android:id="@+id/image_header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/anim_toolbar"
                android:layout_width="match_parent"
                android:layout_height="104dp"
                android:minHeight="?attr/actionBarSize"
                android:gravity="top"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:titleMarginTop="13dp" />


            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                app:tabGravity="fill"
                app:tabMode="scrollable"
                style="@style/MyCustomTabLayout"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_map"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="#f44336"
        android:src="@drawable/ic_maps_my_location" />

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

Hope this will help~

Kaolinite answered 23/3, 2017 at 14:53 Comment(0)
L
3

I am a bit unclear on what is to be achieved here.

  1. Do you not want the TAB to move up and down while scrolling? If so, you want to put the TabLayout outside the CollapsingToolbarLayout. Because anything that you put inside the CollapsingToolbarLayout, will move on scrolling.

From the comment you have put, I have modified your xml to imitate that of the YouTube screen. The toolbar is put outside the coordinator layout since it's pinned permanently and is not affected by the scrolling. Something that's worth mentioning is "One note: all views using the scroll flag must be declared before views that do not use the flag. This ensures that all views exit from the top, leaving the fixed elements behind." This is taken from the android blogpost http://android-developers.blogspot.in/2015/05/android-design-support-library.html. This is why I have moved the toolbar out of the AppBarLayout.

<?xml version="1.0" encoding="utf-8"?>

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

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"/>

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        android:layout_below="@id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

</RelativeLayout>

I have put the TabLayout static, but you can make it scrollable. If this is not what you are looking for, kindly explain pictorially what is to be achieved here. I will be glad to help.

Laicize answered 18/10, 2015 at 14:32 Comment(6)
I want a layout similar to the Youtube app. You can examine the behavior of tabs there. One more addition to this; I want an image inside the toolbar.Acceptable
I was looking at the YouTube app's MainScreen. The Toolbar is pinned with a constant height of 56dp, and the TabLayout is pinned with a constant height of 56dp as well. There is no change to either of them on scrolling the list of videos. There is no CollapsingToolbarLayout used here at all. Again going back to the YouTube app, the toolbar never changes height (never expands), so there is no point in putting an image there. But if you are to use an Image inside the Collapsing ToolbarLayout, you could refer the 'CheeseDetailActivity.java' and its corresponding xml layout 'activity_detail.xml'.Laicize
No. Not the MainScreen. Open the detail screen of some user. You can see the tabs there (Home, Videos, Playlists...)Acceptable
Got it. I have updated my answer. It imitates the exact YouTube screen that you are talking about. The Toolbar is pinned, and the TabLayout moves up and down on scrolling.Laicize
As I commented above; I need an image inside the toolbar. So I need a collapsing toolbar layout.Acceptable
@Acceptable found the solution?Diseur
D
1

I built two samples with parallax and one with RecyclerView on top of AppbarLayout

One with only parallax is

enter image description here

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/htab_maincontent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <!--
    OUTLINE
    <CoordinatorLayout>
        <AppbarLayout>
               <CollapsingToolbarLayout>
                    <ImageView/>
                 <Toolbar/>
                 <TabLayout/>
            </CollapsingToolbarLayout>
        </ AppbarLayout >
        <NestedScrollView/>
    </CoordinatorLayout>
    -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/ivHeader"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@android:color/transparent"
                app:tabIconTint="#F57C00"
                app:tabIndicatorColor="#F57C00"
                app:tabIndicatorHeight="4dp"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="#F5F5F5"
                app:tabTextColor="#FFE0B2" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

And the one that RecyclerView above AppbarLayout is

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/htab_maincontent"
    android:layout_width="match_parent"
    android:background="#EEEEEE"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <!--
    OUTLINE
    <CoordinatorLayout>
        <AppbarLayout>
               <CollapsingToolbarLayout>
                    <ImageView/>
                 <Toolbar/>
                 <TabLayout/>
            </CollapsingToolbarLayout>
        </ AppbarLayout >
        <NestedScrollView/>
    </CoordinatorLayout>
    -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="330dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/ivHeader"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@android:color/transparent"
                app:tabIconTint="#F57C00"
                app:tabIndicatorColor="#F57C00"
                android:translationY="-30dp"
                app:tabIndicatorHeight="4dp"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="#F5F5F5"
                app:tabTextColor="#FFE0B2" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/constraintLayout"
        app:behavior_overlapTop="30dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager2"
            android:layout_width="match_parent"
            android:background="#fff"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:layout_height="match_parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

And setting TabLayout translationY on scroll with

// Check if scrolling up or down
   var initTransitionY = tabLayout.translationY
    tabLayout.post {
        initTransitionY = tabLayout.translationY
    }

appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->

    //Check if the view is collapsed
    if (abs(verticalOffset) >= appbar.totalScrollRange) {
        collapsingToolbar.title = "Collapsed"
    } else {
        collapsingToolbar.title = ""
    }

        tabLayout.translationY =
            initTransitionY + initTransitionY * (verticalOffset / appBarLayout.totalScrollRange.toFloat())

})

For full samples and other samples you can check out this repo

Digger answered 25/10, 2020 at 20:42 Comment(0)
M
0

add android:layout_gravity="bottom" to android.support.design.widget.TabLayout

Menispermaceous answered 17/10, 2015 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.