Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using ActionMode, the status bar turns black on Lollipop

I have a status bar with the following in the theme set on it:

<!-- Base Theme for all "Material"-esque styles. We use NoActionBar      so we can use the Toolbar at runtime. --> <style name="Material" parent="Theme.AppCompat.Light.NoActionBar">     <item name="android:windowDrawsSystemBarBackgrounds">true</item>     <item name="android:windowTranslucentStatus">true</item>     ... </style> 

I also have a DrawerLayout for most of my activities, which sets the color of the status bar to my liking using:

    mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myapp_green)); 

I am using a Toolbar, rather than the default ActionBar, so it exists in my layout (i.e. the navigation drawer draws on top of it).

Everything works fine, except that in one of my activities, I have a multi-select mode with an ActionMode. When this ActionMode is activated (using a long press), it overlays the Toolbar using:

<item name="android:windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item> <item name="actionModeStyle">@style/Material.Widget.ActionMode</item> 

The Material.Widget.ActionMode style is:

<style name="Material.Widget.ActionMode" parent="@style/Widget.AppCompat.ActionMode">     <item name="android:background">@color/myapp_green</item>     <item name="background">@color/myapp_green</item> </style> 

Now, the problem is that, whenever this happens, the status bar turns from the myapp_green color to black. It's almost as if the status bar translucency is turned off (I'm using Android 5.0). I'm wondering how I might be able to get this behavior to not happen, and to keep the status bar color/translucency as-is.

I've tried to add <item name="android:windowTranslucentStatus">true</item> to the action mode's styles, as well as adding <item name="android:statusBarColor">@color/myapp_green</item> in the style for the ActionMode, both without success.

Update:

I wonder if this has something to do with the wonky way that I'm setting the status bar background. All of my Activity classes derive from NavigationDrawerActivity.java:

/**  * An {@link Activity} that supports a Navigation Drawer, which is a pull-out panel for navigation  * menus. This drawer is pulled out from the left side of the screen (right side on RTL devices).  */ public class NavigationDrawerActivity extends ActionBarActivity   implements AdapterView.OnItemClickListener {    private static final String LOGTAG = NavigationDrawerActivity.class.getSimpleName();    private DrawerLayout mDrawerLayout;   private ListView mDrawerList;   private LayoutInflater mInflater;   private NavigationDrawerItemAdapter mAdapter;   private ActionBarDrawerToggle mDrawerToggle;    private NavigationDrawerItem[] mNavigationDrawerItems;    private Toolbar mAppBar;    @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState); // We have to call super.setContentView() here because BaseActivity redefines setContentView(), // and we don't want to use that. super.setContentView(R.layout.navigation_drawer);  mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);      setupNavigationDrawer();   }    @Override   protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState);      // Sync the toggle state after onRestoreInstanceState has occurred.     mDrawerToggle.syncState();   }    @Override   public void onConfigurationChanged(Configuration newConfig) {     super.onConfigurationChanged(newConfig);     mDrawerToggle.onConfigurationChanged(newConfig);   }    @Override   public boolean onCreateOptionsMenu(Menu menu) {     return true;   }    @Override   public boolean onOptionsItemSelected(MenuItem item) {     int id = item.getItemId();      switch(id) {       case android.R.id.home:         return mDrawerToggle.onOptionsItemSelected(item);     }      return super.onOptionsItemSelected(item);   }    /**    * Toggles the state of the navigation drawer (i.e. closes it if it's open, and opens it if    * it's closed).    */   public void toggleNavigationDrawer() {     if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {       closeNavigationDrawer();     } else {       openNavigationDrawer();     }   }    /**    * Opens the navigation drawer.    */   public void openNavigationDrawer() {     mDrawerLayout.openDrawer(GravityCompat.START);   }    /**    * Closes the navigation drawer.    */   public void closeNavigationDrawer() {     mDrawerLayout.closeDrawer(GravityCompat.START);   }    /**    * Initializes items specific to the navigation drawer.    */   private void setupNavigationDrawer() {     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);         mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.wiw_green));          mAppBar = (Toolbar) findViewById(R.id.app_bar);         setSupportActionBar(mAppBar);          ActionBar actionBar = getSupportActionBar();         actionBar.setDisplayHomeAsUpEnabled(true);         actionBar.setHomeButtonEnabled(true);         actionBar.setDisplayShowHomeEnabled(false);          mDrawerToggle = new ActionBarDrawerToggle(           this,                  /* Our context (Activity that hosts this drawer) */           mDrawerLayout,         /* The DrawerLayout where the nav drawer will be drawn */           R.string.drawer_open,  /* Description of "open drawer", for accessibility */           R.string.drawer_close  /* Description of "close drawer", for accessibility */         ) {            /**            * Called when a drawer has settled in a completely closed state.            */           public void onDrawerClosed(View view) {             super.onDrawerClosed(view);             supportInvalidateOptionsMenu();           }            /**            * Called when a drawer has settled in a completely open state.            */           public void onDrawerOpened(View drawerView) {             super.onDrawerOpened(drawerView);             supportInvalidateOptionsMenu();           }         };          mDrawerList = (ListView) mDrawerLayout.findViewById(R.id.drawer_list);          mNavigationDrawerItems = buildNavDrawerItemsList();          setupAdapter(mNavigationDrawerItems);          setupNavigationDrawerHeader();          mDrawerLayout.setDrawerListener(mDrawerToggle);         mDrawerList.setOnItemClickListener(this);       }        @Override       public void onItemClick(AdapterView<?> parent, View aView, int aPosition, long aId) {         // Code not relevant       }        /**        * Set the inner content view of this {@link NavigationDrawerActivity} to have a given layout.        *        * @param aLayoutId The id of the layout to load into the inner content view of this activity.        */       public void setDrawerContent(int aLayoutId) {         LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);         ViewGroup root = (ViewGroup)findViewById(R.id.drawer_content);         inflater.inflate(aLayoutId, root);       }       } 

I actually have to run DrawerLayout.setStatusBarBackgroundColor() for it to have an effect. Just changing colorPrimaryDark in values-v21/styles.xml has no effect on the status bar. I feel like this could be the root of the problem... These classes are being converted from a non-Material theme to a new, Material-like theme, so I'm wondering if I missed something when I did the conversion to the colorPrimaryDark to be recognized correctly.

like image 653
jwir3 Avatar asked May 12 '15 01:05

jwir3


People also ask

How can I change the color of my status bar?

Step 1: After opening the android studio and creating a new project with an empty activity. Step 2: Navigate to res/values/colors. xml, and add a color that you want to change for the status bar. Step 3: In your MainActivity, add this code in your onCreate method.

How can I change the color of my activity bar in Android?

Just go to res/values/styles.edit the xml file to change the color of action bar.


1 Answers

I'm posting an answer here because, while the other solutions were helpful, none of them answered the question exactly. I was able to find out that the call to DrawerLayout.setStatusBarBackgroundColor() was causing the trouble. My solution is the following:

  1. Enable windowTranslucentStatus and windowDrawsSystemBarBackgrounds in the main theme.

  2. Remove the call to DrawerLayout.setStatusBarBackgroundColor() inside of my NavigationDrawerActivity, from which all Activity classes derive.

  3. Set the following styles in my values-v21/styles.xml base theme:

    <item name="android:colorPrimary">@color/app_green</item> <item name="colorPrimary">@color/app_green</item> <item name="android:colorPrimaryDark">@color/app_green_dark</item> <item name="colorPrimaryDark">@color/app_green_dark</item> <item name="android:colorPrimaryDark">?attr/colorPrimaryDark</item> <item name="android:statusBarColor">?attr/colorPrimaryDark</item> 
  4. Inside of the NavigationDrawerActivity class, in its onCreate() method, I execute the following (thanks @Tinadm for this part of the answer): getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

  5. Inside of my class that presents the ActionMode, I added the following methods:

    @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) {   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {     getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);     // This is to highlight the status bar and distinguish it from the action bar,     // as the action bar while in the action mode is colored app_green_dark     getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.app_green_darker));   }    // Other stuff...   return true; }  @Override public void onDestroyActionMode(ActionMode mode) {   mActionMode = null;   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {     getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);     getActivity().getWindow().setStatusBarColor(getResources().getColor(R.color.app_green_dark));   } } 

Re-enabling the translucent status bar when the ActionMode is destroyed enables my navigation drawer to be drawn underneath the status bar. It's also worth noting that the ActionMode overlays the action bar, so it will overlay the navigation drawer if it's pulled out when the ActionMode is enabled (via swiping left-to-right). I am going to disable this functionality when the ActionMode is enabled, so it doesn't confuse users.

like image 103
jwir3 Avatar answered Sep 22 '22 11:09

jwir3