UPDATE
Same issue present in the latest Gmail app. I still don't understand why would Google make such unpleasant UI change. Obsessive in me goes crazy whenever I see it
QUESTION
I have this weird issue with appcompat-v7 23. Issue I am going to describe does not happen with 22 series
You can get source code that reproduces this issuse form https://github.com/devserv/t/ Once built, you can tap and hold an item in the list to activate ActionMode
Issue:
When in ActionMode, appcompat turns status bar to black. This does not happen if I don’t use following
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
in my v21 style but I have to use it because I want my navigation drawer to look behind status bar.
I used to use following to avoid black status bar when ActionMode started and ended
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.appColorPrimaryDark));
}
}
public void onDestroyActionMode(ActionMode actionMode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().getWindow().setStatusBarColor(getResources().getColor(android.R.color.transparent));
}
mMode = null;
}
Above code did not create/avoided status bar turning black, but does not work properly on v23 of appcompat. Instead you see a short black status bar while ActionMode destroyed. It looks like related to the animation that plays when ActionMode destroyed.
I have tried to open bug reports but it has been declined with comment
Don't re-create bugs.
Am I missing something?
Here are the screen shots for normal and action mode
In case only the color is the issue, you can change it. Only to a fixed color resource.
Obvious
?colorPrimaryDark
will not work, not even on API 21.The view responsible for the black status bar background is stored in
AppCompatDelegateImplV7.mStatusGuard
. You can get the delegate by callinggetDelegate()
from your activity and accessmStatusGuard
field by reflection. After starting the action mode you can get a reference to this view and customize it however you like.This was found in AppCompat 24.1.1.
The version 23.0.0 of
v7 appcompat library
introduced an animation that fades in and out the action mode when it's started and finished as you can read here:The changes are made in the method
onDestroyActionMode
inAppCompatDelegateImplV7
:In version 23.0.0 it was changed to:
As you can see
mWrapped.onDestroyActionMode(mode);
is called immediately, not when the animation ends. This is what cause the black status bar in your app and in other apps like Gmail and Keep.The workaround that you found works, but unfortunately is not reliable, because if the animation takes longer you could see the black status bar anyway.
I think Google should correct the issue and call
onDestroyActionMode
only when the animation is really ended. In the mean time you can change this behaviour with a bit of reflections. It is necessary to overrideonSupportActionModeStarted
in your activity and call the methodfixActionModeCallback
:Nobody? Here is the workaround I came up with. Delay.