android - Cuando se usa ActionMode, la barra de estado se vuelve negra en Lollipop
statusbar android-actionmode (9)
Bueno, su solución temporal es llamar a este código cuando más lo necesite o cuando comience el problema.
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 actionMode, 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 actionMode
su actionMode
, la barra de estado se restaurará, así que anule eso también y vuelva a configurar el color de su barra de estado.
Espero eso ayude
Tengo una barra de estado con lo siguiente en el tema establecido:
<!-- 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 con:
mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myapp_green));
Estoy usando una Toolbar
, en lugar de la Toolbar
de ActionBar
predeterminada, por lo que existe en mi diseño (es decir, el cajón de navegación se dibuja sobre ella).
Todo funciona bien, excepto que en una de mis actividades, tengo un modo de selección múltiple con un modo de ActionMode
. Cuando se activa este ActionMode
(con una pulsación larga), 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 barra de estado de translucidez estuviera desactivada (estoy usando Android 5.0). Me pregunto cómo podría lograr que este comportamiento no se produzca, y mantener el color / translucidez de la barra de estado tal como está.
He intentado agregar <item name="android:windowTranslucentStatus">true</item>
a los estilos del modo de acción, así como agregar <item name="android:statusBarColor">@color/myapp_green</item>
en El estilo para el ActionMode
, ambos sin éxito.
Actualizar:
Me pregunto si esto tiene algo que ver con la forma confusa de que estoy configurando el fondo de la barra de estado. Todas mis clases de actividad 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 (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);
}
}
En realidad, tengo que ejecutar DrawerLayout.setStatusBarBackgroundColor()
para que tenga efecto. El solo cambio de colorPrimaryDark
en values-v21/styles.xml
no tiene ningún efecto en la barra de estado. Siento que esta podría ser la raíz del problema ... Estas clases se están convirtiendo de un tema no material a un nuevo tema similar al material, así que me pregunto si me perdí algo cuando hice la conversión al colorPrimaryDark
para ser reconocido correctamente.
El problema podría estar aquí.
<item name="android:background">@color/myapp_green</item>
<item name="background">@color/myapp_green</item>
"android: background" es una sintaxis adecuada, no creo que "background" sea. ¿Por qué necesitas especificar el color de fondo dos veces de todos modos? Retire el segundo y debería estar bien. Si no, espero que mis 2 centavos más abajo sobre el tema de los métodos setBackgroundColor
ayuden.
$ 0.02
En mi experiencia, he encontrado que de vez en cuando el método setBackgroundColor()
en Android se comporta de forma extraña. Cuando eso sucede, uso setBackground()
lugar, y especifico el color en una forma getResources().getDrawable(R.color.xxxx)
: getResources().getDrawable(R.color.xxxx)
. Nunca supe por qué esto resolvió problemas similares que he tenido en el pasado, pero hasta ahora he usado esta solución sin ningún efecto secundario obvio. Puede que no sea la mejor solución (especialmente si ya está configurando un dibujable de fondo), pero resulta útil cuando nada parece funcionar.
Estaba teniendo exactamente el mismo problema que tú. Logré resolverlo usando una solución.
- Lo primero que hice fue eliminar
windowTranslucentStatus=true
de mi tema; - Luego utilicé
getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Para hacer que el contenido llene el área debajo de la barra de estado. - Establecí
<item name="android:colorPrimaryDark">@color/primary_dark</item>
donde primary_dark es "# 51000000". Tenga en cuenta el valor alfa para lograr la misma transparencia que proporciona windowTranslucent. Como mi barra de herramientas es azul, mi barra de estado ahora es azul oscura. Esto solo no resolvió el problema. Cuando el modo de acción está activo, la barra de estado aún era negra en mi caso. Pero ahora, al no usar TranslucentStatusBar, puedo aplicar colores a mi barra de estado, así que utilicé:
@Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { getActivity().getWindow().setStatusBarColor(Color.parseColor("#026592")); return true; }
(Tenga en cuenta que el color que utilicé no tiene alfa. Este es el color RGB que coincide exactamente con mi barra de estado azul transparente).
Estoy publicando una respuesta aquí porque, mientras que las otras soluciones fueron útiles, ninguna de ellas respondió exactamente a la pregunta. Pude descubrir que la llamada a DrawerLayout.setStatusBarBackgroundColor()
estaba causando el problema. Mi solución es la siguiente:
- Habilite
windowTranslucentStatus
ywindowDrawsSystemBarBackgrounds
en el tema principal. - Elimine la llamada a
DrawerLayout.setStatusBarBackgroundColor()
dentro de myNavigationDrawerActivity
, de la cual derivan todas las clases deActivity
. - Establezca los siguientes estilos en mi tema base de
values-v21/styles.xml
:
@color/app_green @color/app_green @color/app_green_dark @color/app_green_dark ?attr/colorPrimaryDark ?attr/colorPrimaryDark
Dentro de la clase
NavigationDrawerActivity
, en su métodoonCreate()
, ejecuto lo siguiente (gracias @Tinadm por esta parte de la respuesta):getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Dentro de mi clase que presenta
ActionMode
, agregué los siguientes métodos:
@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)); } }
Al volver a habilitar la barra de estado translúcida cuando se destruye el ActionMode
se puede dibujar el cajón de navegación debajo de la barra de estado. También vale la pena señalar que ActionMode
superpone a la barra de acción, por lo que se superpondrá al cajón de navegación si se ActionMode
cuando ActionMode
está habilitado (al ActionMode
izquierda a derecha). Voy a deshabilitar esta funcionalidad cuando ActionMode
esté habilitado, para que no confunda a los usuarios.
Me encontré con el mismo problema hace un tiempo y mi resolución fue en onCreateActionMode & onDestroyActionMode configurado y restaurar el color de la barra de estado.
//onCreateActionMode
mStartColor = activity.getWindow().getStatusBarColor();
getWindow().setStatusBarColor(color);
//onDestroyActionMode
activity.getWindow().setStatusBarColor(mStartColor);
Por supuesto, deberá comprobar que está en lolipop antes de usar el método setStatusBarColor, ya que no está disponible antes de L.
Extra: si usa un DrawerLayout, también tendrá que establecer el statusBarColor en él.
mDrawerLayout.setStatusBarBackground(new ColorDrawable(color));
¡Espero que ayude!
Mirando a través de la documentación de Android en las barras del sistema translúcido
Si está creando un tema personalizado, configure uno de estos temas (Theme.Holo.NoActionBar.TranslucentDecor y Theme.Holo.Light.NoActionBar.TranslucentDecor) como el tema principal o incluya las propiedades de estilo window TranslucentNavigation 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 usar tanto WindowTranslucentNavigation como windowTranslucentStatus en su ActionBarStyle.
Si bien usé las soluciones anteriores anteriormente, hay más problemas al agregar un cajón de navegación, si desea que el cajón se dibuje detrás de la barra del sistema, y hay muchos problemas relacionados con la configuración y el borrado de las banderas de las ventanas o el color de la barra de estado (incluso el color oficial). La aplicación de Gmail tiene estos fallos!)
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);
}
}
Obviamente, esto es un gran truco, y no se anima exactamente como lo hace la barra de acción contextual, pero lo hace para mí. Apoyos a https://.com/a/38702953/1317564 para dar con la idea.
Tenga en cuenta que esto solo es necesario si está utilizando un cajón de navegación o si tiene estos atributos establecidos en sus valores-v21 / theme.xml:
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
De lo contrario, probablemente funcionará simplemente llamando a setStatusBarColor(...)
en onSupportActionModeStarted()
y onSupportActionModeFinished()
, y esto es lo que estaba haciendo antes de agregar un cajón de navegación.
Tengo el mismo problema y lo resolví de la siguiente manera.
El problema fue con la anulación del mismo color para todas las vistas. Pero no puedo 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);
}
}