Search code examples
javaandroidtoolbarcontextual-action-bar

Why is Contextual Action Bar getting different style when calling startSupportActionMode inside onCreate method?


I'm using appcompat-v7:22.2.0 Toolbar widget and trying to show the contextual action bar (cab).

To show this theme problem I wrote 2 methods startSupportActionMode and startSupportActionModeDelay. The first call AppCompatActivity.startSupportActionMode immediately from activity onCreate and the last one wait for a second to call AppCompatActivity.startSupportActionMode.

The result is as follows:

Normal Activity

Normal Activity

Calling startSupportActionModeDelay

Calling startSupportActionModeDelay

Calling startSupportActionMode

Calling startSupportActionMode

I found many issues related with the CAB background color or suggesting to style it using actionModeStyle, but this is not what I want.

What I wanted is to get always the same result as calling startSupportActionModeDelay but immediately from onCreate method (without the need of creating a thread, etc - those are here just to illustrate the problem) because I will have to recreate the context action bar after a orientation change, for example.

Here is the code until now:

RecyclerViewActivity.java

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class RecyclerViewActivity extends AppCompatActivity {
    private ActionMode.Callback mActionModeCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);

        initToolbar();
        initSupportActionMode();

        //calling the method below causes the CAB to get a light theme
        //startSupportActionMode();

        //calling the method below causes the CAB to get a dark theme
        //startSupportActionModeDelay();
    }

    private void initToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final ActionBar actionBar = getSupportActionBar();

        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);
        }
    }
    private void initSupportActionMode() {
        mActionModeCallback = new ActionMode.Callback() {
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
            }
        };
    }

    private void startSupportActionMode() {
        startSupportActionMode(mActionModeCallback);
    }

    private void startSupportActionModeDelay() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000l);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        startSupportActionMode(mActionModeCallback);
                    }
                });
            }
        }).start();
    }
}

layout/activity_recycler_view.xml

<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:fitsSystemWindows="true">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        android:paddingTop="?attr/actionBarSize"/>

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:elevation="4dp"
            android:background="?attr/colorPrimary"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            android:fitsSystemWindows="true">

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

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

values/styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="BaseTheme" />

    <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorControlHighlight">@color/accent_translucent</item>
        <item name="colorAccent">@color/accent</item>

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

    <color name="primary">#00BCD4</color>
    <color name="primary_dark">#0097A7</color>
    <color name="accent">#FFEB3B</color>
    <color name="accent_translucent">#80FFEB3B</color>
    <color name="accent_bright">#FFF493</color>
</resources>

Solution

  • Adding the following lines to values/styles.xml / BaseTheme solved the problem:

        <item name="actionBarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
    

    Although I could not figure out what exactly was happening since this themes were already defined on my Toolbar widget and the setSupportActionBar was called before startSupportActionMode.

    Maybe the context action bar was being created before the styles from Toolbar widget could be parsed by the setSupportActionBar.