Toolbar and Contextual ActionBar with AppCompat-v7

AndroidAndroid 5.0-LollipopAndroid AppcompatAndroid Toolbar

Android Problem Overview


I am working on using the newly added Toolbar that was introduced in Lollipop and the AppCompat-v7 library. I followed this guide on setting up the Toolbar I noticed that when you invoke something that will bring up the contextual ActionBar (such as highlighting text for copy/pasting), that it will push the Toolbar down on the page. You can see what I am talking about in the image at the bottom of the page:

So, essentially, I set it up like this. I have the Toolbar defined in an xml file that I use with include tags:

<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:background="?attr/colorPrimary"/>

Then, I instantiate it in my view:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/root"
    tools:context=".MainActivity">

    <include
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/> 

    <!-- Rest of view -->

    </LinearLayout>

In code, I set it up like so:

    // On Create method of activity:
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

Does anyone know how to make it so that the Contextual ActionBar comes overtop of the Toolbar?

Toolbar and Contextual ActionBar

Android Solutions


Solution 1 - Android

Update:

Solution: use the windowActionModeOverlay property. Set this in your theme:

<item name="windowActionModeOverlay">true</item>

and the actionmode will be shown over the action bar instead of pushing it down. (If you're not using the latest AppCompat then you need to add the "android:" prefix to the property). It basically lets AppCompat know that you have a toolbar located in the top of the screen and that it should draw the ActionMode on top of it.


Old answer/workaround:

I ran into the same problem. No matter what theme I set, it always pushes down the Toolbar I set as ActionBar. I tried with and without the support library, but it didn't matter.

Unfortunately I was not able to fix it so I have built a workaround instead. In my ActionModeCallback's onCreateActionMode I hide the action bar:

actionBarToolbar.setVisibility(View.GONE);

and in onDestroyActionModeI show it again:

actionBarToolbar.setVisibility(View.VISIBLE);

The hiding/showing happens so quickly it is not noticeable on my test devices. There is of course a downside: although the enter-animation still works, the exit-animation of the contextual action bar gets lost because the Toolbar immediately pops over it. But until we come across a better solution I guess we are stuck with this.


(My Activity is actually extending a custom BaseActivity class which has a method called getActionBarToolbar(), taken from the Google I/O 2014 app source code, so I can easily get fetch the Toolbar:

BaseActivity activity = (BaseActivity) getActivity();
activity.getActionBarToolbar().setVisibility(View.GONE);

Too bad the I/O app does not use the contextual action bar.)

Solution 2 - Android

Do not start it on your activity, but on your toolbar. In you activity:

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

and you have to use

<item name="windowActionModeOverlay">true</item>

Solution 3 - Android

Just a small addition: For

<item name="windowActionModeOverlay">true</item>
to work it's important to call super.onCreate(savedInstanceState) BEFORE calling setContentView(R.layout.your_activity) in your activity. It really makes a difference in this case!

Solution 4 - Android

In my case, <item name="windowActionModeOverlay">true</item>did not work, but this work:<item name="android:windowActionModeOverlay">true</item>,the android is the key.

Solution 5 - Android

Jacob's solution worked for me but the contextual ActionBar was transparent and the Toolbar visible through it. This can be resolved as follows:

<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
    ....
    ....
    <item name="actionModeStyle">@style/CustomActionMode</item>
</style>

<style name="CustomActionMode" parent="@style/Widget.AppCompat.ActionMode">
    <item name="background">@color/primary_material_light</item>
</style>

The theme "AppTheme.Base" must be the one applied to the Toolbar.

More details regarding contextual ActionBar styling:

https://stackoverflow.com/questions/27458421/how-to-customize-the-contextual-action-bar-using-appcompat-in-material-design

Solution 6 - Android

Very useful method to bring toolbar to front toolbar.bringToFront()

Solution 7 - Android

Another small addition: make sure to set at least an empty screen in the activity via setContentView(R.layout.empty_screen) if you load the whole ui in fragments (ft.replace(android.R.id.content, fragment)).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionarietsView Question on Stackoverflow
Solution 1 - AndroidJacob RasView Answer on Stackoverflow
Solution 2 - AndroidFrankView Answer on Stackoverflow
Solution 3 - AndroidDaniel VeihelmannView Answer on Stackoverflow
Solution 4 - AndroidJenkynView Answer on Stackoverflow
Solution 5 - AndroidPeteView Answer on Stackoverflow
Solution 6 - Androidkunal.cView Answer on Stackoverflow
Solution 7 - AndroidAndreas WengerView Answer on Stackoverflow