Cuando se utiliza ActionMode, la barra de estado se vuelve negra en Lollipop

Tengo una barra de estado con lo siguiente en el tema fijado en él:

<!-- 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> 

También tengo un DrawerLayout para la mayoría de mis actividades, que establece el color de la barra de estado a mi gusto usando:

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

Estoy utilizando una Toolbar , en lugar de la predeterminada ActionBar , por lo que existe en mi diseño (es decir, el cajón de navegación se basa en la parte superior de la misma).

Todo funciona bien, excepto que en una de mis actividades, tengo un modo de selección múltiple con un ActionMode . Cuando se activa este modo de ActionMode (con una pulsación prolongada), se superpone a la Toolbar con:

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

El estilo Material.Widget.ActionMode es:

 <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> 

Ahora, el problema es que, cuando esto sucede, la barra de estado cambia del color myapp_green a negro. Es casi como si la translucidez de la barra de estado estuviera desactivada (estoy usando Android 5.0). Me pregunto cómo podría ser capaz de conseguir que este comportamiento no suceda, y mantener la barra de estado de color / translucidez como está.

He intentado añadir <item name="android:windowTranslucentStatus">true</item> a los estilos del modo de acción, además de añadir <item name="android:statusBarColor">@color/myapp_green</item> El estilo para el ActionMode , ambos sin éxito.

Actualizar:

Me pregunto si esto tiene algo que ver con la manera wonky que estoy estableciendo el fondo de la barra de estado. Todas mis clases de actividad se derivan de 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 (ie 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); } } 

De hecho, tengo que ejecutar DrawerLayout.setStatusBarBackgroundColor() para que tenga un efecto. El solo cambio de colorPrimaryDark en values-v21/styles.xml no tiene ningún efecto en la barra de estado. Siento que esto podría ser la raíz del problema … Estas clases se están convirtiendo de un tema no material a un nuevo tema, Material-como, así que me pregunto si me perdí algo cuando hice la conversión a la colorPrimaryDark sea ​​reconocido correctamente.

Estoy publicando una respuesta aquí, porque, mientras que las otras soluciones fueron útiles, ninguno de ellos respondió a la pregunta exactamente. Pude descubrir que la llamada a DrawerLayout.setStatusBarBackgroundColor() estaba causando el problema. Mi solución es la siguiente:

  1. Habilite windowTranslucentStatus y windowDrawsSystemBarBackgrounds en el tema principal.
  2. Eliminar la llamada a DrawerLayout.setStatusBarBackgroundColor() dentro de mi NavigationDrawerActivity , de la que derivan todas las clases de Activity .
  3. Establezca los estilos siguientes en mi tema base values-v21/styles.xml :
         @ Color / app_green
         @ Color / app_green
         @ Color / app_green_dark
         @ Color / app_green_dark
         ? Attr / colorPrimaryDark
         ? Attr / colorPrimaryDark
  1. Dentro de la clase NavigationDrawerActivity , en su método onCreate() , ejecuto lo siguiente (gracias a @Tinadm por esta parte de la respuesta): getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

  2. Dentro de mi clase que presenta el ActionMode , he añadido los siguientes métodos:

     @Anular
     Public boolean onPrepareActionMode (modo ActionMode, menú Menú) {
       If (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP) {
         GetActivity (). GetWindow (). ClearFlags (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
         // Esto sirve para destacar la barra de estado y distinguirla de la barra de acción,
         // como la barra de acción mientras está en el modo de acción está coloreada app_green_dark
         GetActivity (). GetWindow (). SetStatusBarColor (getResources (). GetColor (R.color.app_green_darker));
       }

       // Otras cosas...
       Devuelve verdadero;
     }

     @Anular
     Public void onDestroyActionMode (modo ActionMode) {
       MActionMode = nulo;
       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));
       }
     }

ActionMode la barra de estado translúcido cuando el modo de ActionMode se destruye permite que mi cajón de navegación se ActionMode debajo de la barra de estado. También vale la pena notar que el ActionMode superpone la barra de acción, por lo que superpondrá el cajón de navegación si se extrae cuando el ActionMode está habilitado (pasando de izquierda a derecha). Voy a deshabilitar esta funcionalidad cuando el ActionMode está habilitado, por lo que no confundir a los usuarios.

Así su solución temporal es llamar a este código cuando más lo necesita o cuando el problema se inicia

 if(Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP){ getWindow().setStatusBarColor(Color.BLUE); // or Color.TRANSPARENT or your preferred color } 

EDITAR

Has probado esto

 //ActionMode.getCustomView().setBackgroundColor.(Color.TRANSPARENT); 

.

 @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { //but this time you let the actionmode's view change the statusbar's //visibility ActionMode.getCustomView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LOW_PROFILE //or preferred one); return true; } 

Cuando se destruye tu ActionMode , se restaurará la barra de estado, así que también anula esto y vuelve a configurar tu color statusBar.

Espero eso ayude

Estaba teniendo exactamente el mismo problema que tú. Me las arreglé para resolverlo usando una solución alternativa.

  1. Lo primero que hice fue eliminar windowTranslucentStatus=true de mi tema;
  2. Entonces utilicé getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); Para que el contenido llene el área debajo de la barra de estado.
  3. He establecido <item name="android:colorPrimaryDark">@color/primary_dark</item> donde primary_dark es "# 51000000". Tenga en cuenta el valor alfa para lograr la misma trasparencia que windowTranslucent proporciona. Como mi barra de herramientas es azul, mi barra de estado es ahora azul oscuro.
  4. Esto por sí solo no resolvió el problema. Cuando el modo de acción está activo, la barra de estado todavía era negra en mi caso. Pero ahora, no usando translucentStatusBar, puedo aplicar colores a mi barra de estado, así que usé:

     @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { getActivity().getWindow().setStatusBarColor(Color.parseColor("#026592")); return true; } 

(Tenga en cuenta que el color que he usado no tiene alpha.Esto es el color RGB que coincide exactamente con mi barra de estado semi azul oscuro transparente).

Me encontré con el mismo problema hace un tiempo y mi resolución fue en onCreateActionMode & onDestroyActionMode establecer y restaurar el color de la barra de estado.

 //onCreateActionMode mStartColor = activity.getWindow().getStatusBarColor(); getWindow().setStatusBarColor(color); //onDestroyActionMode activity.getWindow().setStatusBarColor(mStartColor); 

Por supuesto youll necesidad de comprobar que su en lolipop antes de usar el método setStatusBarColor como su no disponible pre L.

Extra: Si utiliza un DrawerLayout, tendrá que establecer el statusBarColor en él también.

 mDrawerLayout.setStatusBarBackground(new ColorDrawable(color)); 

¡Espero que ayude!

Mirando a través de la documentación de Android sobre las barras del sistema Translucent

Si está creando un tema personalizado, defina uno de estos temas (Theme.Holo.NoActionBar.TranslucentDecor y Theme.Holo.Light.NoActionBar.TranslucentDecor) como el tema principal o incluya las propiedades de estilo windowTranslucentNavigation y windowTranslucentStatus en su tema.

Por lo tanto, si está utilizando las bibliotecas de soporte, su estilo debe extender algunos de los estilos de AppCompat y utilizar windowTranslucentNavigation y windowTranslucentStatus en su ActionBarStyle.

El problema puede estar aquí.

 <item name="android:background">@color/myapp_green</item> <item name="background">@color/myapp_green</item> 

"Androide: fondo" es una sintaxis adecuada, no creo que "fondo" es. ¿Por qué necesita especificar el color de fondo dos veces de todos modos? Quite el segundo y debe estar bien. Si no, entonces espero que mis 2 centavos de abajo sobre el tema de los métodos setBackgroundColor ayudar.

0,02 $

En mi experiencia, he encontrado que de vez en cuando el método setBackgroundColor() en Android se comporta de manera extraña. Cuando eso sucede, yo uso setBackground() lugar, y especifico el color en una forma getResources().getDrawable(R.color.xxxx) : getResources().getDrawable(R.color.xxxx) . Nunca he descubierto por qué esto resolvió problemas similares que he tenido en el pasado, pero he utilizado esta solución hasta ahora sin efectos secundarios obvios. Puede que no sea la mejor solución (especialmente si ya está configurando un fondo dibujable), pero resulta útil cuando nada parece funcionar.

Tengo el mismo problema y lo resolví de la siguiente manera

El problema fue con la sustitución del mismo color para todos los views.But no es capaz de ir con R.color.mycolor y Color.parseColor("#412848") me salvó.

  @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { super.onPrepareActionMode(mode, menu); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window w = getActivity().getWindow(); w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } return true; } @Override public void onDestroyActionMode(ActionMode mode) { super.onDestroyActionMode(mode); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window w = getActivity().getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } } 

Si bien he utilizado las soluciones anteriores anteriormente, hay más problemas al agregar un cajón de navegación, si desea que el cajón dibuje detrás de la barra del sistema, y ​​tantos problemas relacionados con la configuración y borrado de banderas de ventana o el color de barra de estado La aplicación de Gmail tiene estas fallas!)

Aquí está la solución que uso ahora:

 @Override public void onSupportActionModeStarted(@NonNull ActionMode mode) { super.onSupportActionModeStarted(mode); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Post this so it ideally happens after the window decor callbacks. new Handler().post(new Runnable() { @Override public void run() { try { final AppCompatDelegate delegate = getDelegate(); final Class clazz = Class.forName("android.support.v7.app.AppCompatDelegateImplV7"); final Field mStatusGuardField = clazz.getDeclaredField("mStatusGuard"); mStatusGuardField.setAccessible(true); final View mStatusGuard = (View) mStatusGuardField.get(delegate); if (mStatusGuard != null) { mStatusGuard.setBackgroundColor(/* Should match your desired status bar color when the action mode is showing, or alternatively you could use Color.TRANSPARENT here and just update the colors through getWindow().setStatusBarColor() below. The key is to avoid the black status guard from appearing. */); } } catch (Exception e) { /* Log or handle as desired. */ } } }); // Also set the status bar color. This is to avoid a momentary frame or // two where the black will still be visible. getWindow().setStatusBarColor(/* Should match your desired status bar color when the action mode is showing. */); } } @Override public void onSupportActionModeFinished(@NonNull ActionMode mode) { super.onSupportActionModeFinished(mode); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Reset to the theme's colorPrimaryDark. This would normally result in // the black status guard being seen momentarily, but because we set it // to the same color as the action mode background, this intermediate // state is not visible. getWindow().setStatusBarColor(Color.TRANSPARENT); } } 

Esto es obviamente un gran hack, y no se anima exactamente como la barra de acción contextual, pero hace el truco para mí. Props a https://stackoverflow.com/a/38702953/1317564 para llegar a la idea.

Tenga en cuenta que esto sólo es necesario si está utilizando un cajón de navegación o de lo contrario tienen estos atributos en sus valores-v21 / theme.xml:

 <item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:statusBarColor">@android:color/transparent</item> 

De lo contrario, probablemente trabajará para llamar a setStatusBarColor(...) en onSupportActionModeStarted() y onSupportActionModeFinished() , y esto es lo que estaba haciendo antes de agregar un cajón de navegación.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.