My application uses the app theme that inherits Theme.MaterialComponents.Light.NoActionBar. When user selects a list item and enters the contextual action mode, I want to change the action bar to dark grey color. I am using following code to achieve same:
In themes.xml:
<item name="windowActionModeOverlay">true</item>
<item name="actionModeStyle">@style/Widget.App.ActionMode</item>
<item name="actionModeCloseDrawable">@drawable/ic_close_24dp</item>
<item name="actionBarTheme">@style/ThemeOverlay.MaterialComponents.Dark.ActionBar</item>
In styles.xml:
<style name="Widget.App.ActionMode" parent="Widget.AppCompat.ActionMode">
<item name="background">@color/grey_100</item>
</style>
In my fragment:
val callback = object: ActionMode.Callback {
override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
requireActivity().menuInflater.inflate(R.menu.contextual_action_bar, menu)
return true
}
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {return false}
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {return false}
override fun onDestroyActionMode(mode: ActionMode?) {}
}
val actionMode = requireActivity().startActionMode(callback)
actionMode?.title = "1 selected"
With this code, I get following result:
How can we change this code so that it also changes the status bar background and icon colors? Following is the example of how many apps including Google Files app does this:
Notice how it correctly changes status bar background color as well as icon colors accordingly.
I have already tried this answer but it does not result in a smooth transition as many users have commented there. Is there any standard way to achieve the desired behaviour?


There are two requests when the contextual action bar (CAB) is show/hidden:
Sync color animation between CAB & status bar
You can animate the change of the status bar color using
ArgbEvaluatorwith an adjusted duration that tends to the CAB duration (with trial and error it's near 300 msec; I have no documentation clue for the exact value, but you can adjust that to your needs):And this need to be called with the appropriate colors within
onCreateActionMode&onDestroyActionMode:Toggle status bar icon light mode
For API level below 30 (Android R), use
systemUiVisibility, andWindowInsetsControllerfor API level 30 and above:For some reason the
WindowInsetsControllerdidn't work for me, even by using the below 4 versions, but thankfully the old flag works, so I kept it in API level > 30:So, the working demo:
Preview:
UPDATE
Another approach
Instead of animating the status bar to sync with the CAB, you can instead disable the animation. But this requires you to use a customView to the CAB instead of a menu.
There are two places to do that:
When the CAB is shown
Do it whenever you call
startSupportActionMode:When the CAB is hidden:
Do it in
onDestroyActionModeThe downside is that no animation anymore, and there is a delay to show the CAB because it is just hidden using the alpha, so the animation is still consumed but invisible because of setting the alph. And this requires you to to toggle the status bar color after some delay which is assumed by 300 millisec in the first approach: