tato.rodrigo tato.rodrigo - 29 days ago 13
Java Question

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>

Answer

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.