Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the Android L contacts app collapse its toolbar?

I've been trying to reproduce the way that the Contacts app on version 5.0 collapses the toolbar when the listview is scrolled.

Gallery of screenshots demonstrating the desired interaction Note the collapse of the toolbar in stages, where it displays search+last contact, fades last contact, collapses last contact, collapses search, leaving only the tabs.

So far, I have a toolbar sitting above a recyclerview in a LinearLayout, and the toolbar is used as an actionbar, not standalone.

I can't figure out how to intercept the touch event on the recyclerview and make it shrink the toolbar, and then return the scroll event to the recyclerview. I tried putting the entire thing in a scrollview, but then the recyclerview couldn't calculate it's height properly and displayed no content. I tried overriding onscroll on the recyclerview, and found that it will only notify me when a scroll event started, and provide me with the first visible card id.

The way that looks right, but I can't get working for the life of me, is this:

getSupportActionBar().setHideOnContentScrollEnabled(true);

Which returns:

 Caused by: java.lang.UnsupportedOperationException: Hide on content scroll is not supported in this action bar configuration.

Using a traditional actionbar, putting a toolbar below it, and setting hideoncontentscrollenabled also didn't work, scrolling never triggered the hide method on the actionbar.

-- edit -- I was able to get hideOnContentScrollEnabled working on a listview with a traditional actionbar, but the behavior is not the same as the contacts app. This is clearly not the method they used-- it simply triggers .hide() on the actionbar when a fling event occurs on a listview, which is notably different from the contacts app, which drags the toolbar along with the scroll event. -- /edit --

So I abandoned that route, and put fill_parent on the cardview height, and animated a collapse on the toolbar. But how do I trigger it so that it follows the touch event and then returns the touch event to the recyclerview?

activity_main.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:attr/actionBarSize"
        android:background="@color/colorPrimary"
        />

    <fragment android:name="me.myapplication.FragmentTab"
          android:id="@+id/tab_fragment"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />
</LinearLayout>

fragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="8dp"
    android:background="#eeeeee"
    >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        />

</LinearLayout>

styles.xml

...
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...

MainActivity.java

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);

// Disable the logo in the actionbar, as per material guidelines
toolbar.getMenu().clear();
toolbar.setTitle("My toolbar");
setSupportActionBar(toolbar);
like image 959
Preston Avatar asked Oct 24 '14 22:10

Preston


People also ask

Where is the contact list in Android phone?

On your Android phone or tablet, open the Contacts app . At the bottom, tap Contacts.


5 Answers

I haven't investigated the source code yet but this guy seems to have made life easy yet enlightening.

https://github.com/ksoichiro/Android-ObservableScrollView

EDIT

Google has just released Android Design Library. Please take a look as it contains all the effects of collapsing toolbars and much more.

like image 87
humblerookie Avatar answered Oct 19 '22 12:10

humblerookie


Well, I have no idea how they do it, but... why don't you take a peek to the source code? Luckily for us, the Contacts app is still open-source on Android L (others weren't as lucky as Contacts, like Mail, which does not work anymore on L; or Keyboard, which they stopped updating anymore since the launch of their propietary Google Keyboard).

Anyway, here's the source code I think you should look at: https://github.com/android/platform_packages_apps_contacts/blob/master/src%2Fcom%2Fandroid%2Fcontacts%2Factivities%2FActionBarAdapter.java

Note the method update(boolean skipAnimation) in Line 311, which calls animateTabHeightChange(int start, int end) (Line 437).

My guess is all the magic happens there ;-)

like image 23
jrub Avatar answered Oct 19 '22 13:10

jrub


As of June 2015, your desired effect can be accomplished via the so called CollapsingToolbarLayout of the new design support library.

Based on the sample code here, I am figuring that:

  • the search cardview is child of the toolbar
  • the missed call cardview belongs to the collapsingtoolbar with the collapseMode attribute set to pin

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

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:fitsSystemWindows="true"
        app:layout_scrollFlags="scroll|enterAlwaysCollapsed|enterAlways">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:fitsSystemWindows="false"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways">

            <!-- Search layout -->
            <android.support.v7.widget.CardView   
            </android.support.v7.widget.CardView>

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

        <!-- Last call card view-->
        <android.support.v7.widget.CardView
            app:layout_collapseMode="pin">               
        </android.support.v7.widget.CardView>

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

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

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/primary_color"
        app:layout_scrollFlags="scroll"/>

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

</LinearLayout>

like image 2
appoll Avatar answered Oct 19 '22 12:10

appoll


No third party library is required now! Android is officially providing library. You can collapse the toolbar and do many other tweaks.

Check this android-developer's blog

And don't forget to add this dependency in your build.gradle file.

compile 'com.android.support:design:22.2.0'

like image 2
Apurva Avatar answered Oct 19 '22 11:10

Apurva


I found this library that seems to do what you're looking for: https://github.com/kmshack/Android-ParallaxHeaderViewPager and this https://github.com/flavienlaurent/NotBoringActionBar

You can play the video to see the behavior: https://www.youtube.com/watch?v=sCP-b0a1x5Y

It might not be the 'new' standard way of doing it with ToolBar, but it might give you an idea by inspecting the code. It seems to attach a OnScrollListener to the scrolling content and then trigger changes on the size of the bar.

like image 1
Alécio Carvalho Avatar answered Oct 19 '22 13:10

Alécio Carvalho