88

I've seen extended height app bar's in the Google Design App Bar guidelines. How do I implement these in Android Lollipop?

Chris Banes
  • 31,763
  • 16
  • 59
  • 50

2 Answers2

145

You need to use the new Toolbar widget to achieve this. Toolbar has special handling for it's minimum height to declare the amount of space which is used for buttons (and actions).

In the example below, we're setting the height to be 128dp (which is 56dp + 72dp as defined in the spec), but keeping the android:minHeight as the standard actionBarSize (which is usually 56dp). This means that the buttons and actions are constrained to be positioned vertically in the top 56dp. We can then use android:gravity to position the title at the bottom.

<Toolbar
    android:id="@+id/toolbar"
    android:layout_height="128dp"
    android:layout_width="match_parent"
    android:minHeight="?android:attr/actionBarSize"
    android:background="?android:attr/colorPrimary"
    android:gravity="bottom" />

If you're using AppCompat, then change the declaration to use android.support.v7.widget.Toolbar instead and use it's attributes.

Chris Banes
  • 31,763
  • 16
  • 59
  • 50
  • 3
    If using `layout_height` is the way to go, I expect the workaround described by monsoon here is also not a workaround, but the proper way to go? https://code.google.com/p/android/issues/detail?id=77874 – Thomas Keller Oct 21 '14 at 16:43
  • Great but according to the metrics in the guidelines 56+72dp if portrait. Landscape 48dp+72dp. Hence my wish for something automagic/built-in. Can't specify actionBarSize + 72dp, and would prefer not to duplicate the actionBarSize qualifiers for landscape/portrait/tablet/phone. – Mattias Isegran Bergander Oct 21 '14 at 17:55
  • 3
    I'd love to able to declare expressions for dimensions too, but we can't. – Chris Banes Oct 21 '14 at 18:06
  • 2
    `android:gravity="bottom"` by itself places it too close to the bottom. Probably should add `android:paddingBottom="16dp"` . 16dp from the metrics spec. – Mattias Isegran Bergander Oct 21 '14 at 18:45
  • So you just use the toolbar as normal with your layour? setSupportActionBar and setTitle? – Yoavst Oct 21 '14 at 19:28
  • 37
    For bonus points, size the action bar using increments, e.g. `@dimen/action_bar_size_x2`, and use 112dp on phones, 128dp on tablets – Roman Nurik Oct 21 '14 at 19:50
  • 7
    `android:paddingBottom` introduces strange spacing when `buttonGravity` is set to `bottom`. The `titleMarginBottom` attribute seems like the better option here, no? – Paul Burke Oct 25 '14 at 15:43
  • 1
    @ChrisBanes Can we set the gravity for existing text in toolbar. – Akshay Mukadam Nov 06 '14 at 14:35
  • Can you please explain, what is the meaning of extended toolbar, related to app. – Tushar Pandey Nov 13 '14 at 01:15
  • ok-ok i got the meaning by viewing this link, https://dribbble.com/shots/1800786-Concert-app-discover-concerts-calendar-Material-Design?list=tags&tag=material_design&offset=10 . BIG thanks. – Tushar Pandey Nov 13 '14 at 01:18
  • 5
    @RomanNurik how does the expanded toolbar in calendar app work? Any hints – Raghunandan Nov 20 '14 at 11:54
  • @RomanNurik I'd like to know how the toolbar in calendar app works too – edoardotognoni Nov 21 '14 at 09:09
  • Can you please explain how to add floating action buttons over the toolbar? Should we use relative layouts or is there any proper way? – Emre Aktürk Dec 10 '14 at 10:14
  • @ChrisBanes how can I place the title in the middle? –  Oct 26 '15 at 16:34
3

Thanks for your question, its answer, and moreover for the implementation of the toolbar in the native and the supportlibrary :)

And we can play more. We can, at runtime, play with the Height and the MinimalHeight.

The height is the ToolBar height, it's simple, every body understand, and the gravity acts according to that height.

The minimalHeight is more tricky and should not be at minimum 56dp. This minHeight is used to place the line of your menuItem. This line is at the midlle of your minHeight.

So you can add this code to your activity to see by yourself the difference. :)

Runnable toolBarAnimator=new Runnable() {
        @Override
        public void run() {
            if(postICS){
//                toolbar.setTranslationX(iteration);
//                toolbar.setElevation(iteration);
                toolbar.setMinimumHeight(iteration * 5);
                toolbar.getLayoutParams().height++;
            }
            uiThreadHanlder.postDelayed(this,16);
            iteration++;
            if(iteration>150)iteration=0;
        }
    };
    Handler uiThreadHanlder=new Handler();
    int iteration=0;


    @Override
    protected void onResume() {
        super.onResume();
        //launch the animation
        uiThreadHanlder.postDelayed(toolBarAnimator, 1000);
    }


    @Override
    protected void onPause() {
        super.onPause();
        //stop the animation
        uiThreadHanlder.removeCallbacks(toolBarAnimator);
    }

Where toolbar is:

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

When doing this you obtain: enter image description here

but if you leave the animation continue you obtain: enter image description here

This is why, setting your toolbar android:layout_height to wrap_content is a good option in most of the case, because the Toolbar will adapt its height according to its contents (and you can change the content at runtime :)

And this is also how you change your toolbar size at runtime.

Thanks Chris Banes for the amazing work you did on the actionbar.

  • @MohammadHadi I'm imagining that postICS would be defined something like: `boolean postICS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;` – dm78 Jan 27 '16 at 00:11