programacion - ocultar iconos de la barra de estado android
Icono de la barra de herramientas teñido en Android (6)
He notado que al usar los temas de AppCompat, los iconos predeterminados de la barra de herramientas se tiñen con el atributo colorControlNormal
en mi estilo.
<style name="MyTheme" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/yellow</item>
</style>
Como puede ver arriba, sin embargo, no sucede con todos los íconos. Proporcioné el signo "más", que obtuve de los íconos oficiales, y no se tiñe (usé la versión "blanca" del png). Por lo que he entendido de esta question , el sistema tiñe solo los íconos con solo un canal alfa. ¿Es esto cierto?
Si es así : ¿Hay un lugar donde pueda encontrar íconos de material oficial definidos por alfa? Si no es así, y si los iconos de la barra de herramientas deben estar marcados solo con caracteres alfa, ¿cómo espera Google que utilicemos los iconos provistos en una barra de herramientas?
En algún lugar del SDK encontré algunos íconos que terminaban en _alpha.png
, y realmente se _alpha.png
bien. Sin embargo, necesito el conjunto completo de íconos de material, y de las fuentes oficiales solo pude encontrar los white
, grey600
y black
.
Aplicar un ColorFilter
en tiempo de ejecución sería un poco doloroso, y mi barra de herramientas real, con algunos iconos tintados y otros no, se ve bastante mal.
Aquí está la solución que utilizo. Llame a tintAllIcons después de onPrepareOptionsMenu o la ubicación equivalente. El motivo de mutate () es si utiliza los iconos en más de una ubicación; sin el mutado, todos tomarán el mismo tinte.
public class MenuTintUtils {
public static void tintAllIcons(Menu menu, final int color) {
for (int i = 0; i < menu.size(); ++i) {
final MenuItem item = menu.getItem(i);
tintMenuItemIcon(color, item);
tintShareIconIfPresent(color, item);
}
}
private static void tintMenuItemIcon(int color, MenuItem item) {
final Drawable drawable = item.getIcon();
if (drawable != null) {
final Drawable wrapped = DrawableCompat.wrap(drawable);
drawable.mutate();
DrawableCompat.setTint(wrapped, color);
item.setIcon(drawable);
}
}
private static void tintShareIconIfPresent(int color, MenuItem item) {
if (item.getActionView() != null) {
final View actionView = item.getActionView();
final View expandActivitiesButton = actionView.findViewById(R.id.expand_activities_button);
if (expandActivitiesButton != null) {
final ImageView image = (ImageView) expandActivitiesButton.findViewById(R.id.image);
if (image != null) {
final Drawable drawable = image.getDrawable();
final Drawable wrapped = DrawableCompat.wrap(drawable);
drawable.mutate();
DrawableCompat.setTint(wrapped, color);
image.setImageDrawable(drawable);
}
}
}
}
}
Esto no solucionará el desbordamiento, pero para eso, puedes hacer esto:
Diseño:
<android.support.v7.widget.Toolbar
...
android:theme="@style/myToolbarTheme" />
Estilos:
<style name="myToolbarTheme">
<item name="colorControlNormal">#FF0000</item>
</style>
Esto funciona a partir de appcompat v23.1.0.
De hecho, pude hacer esto en API 10 (Gingerbread) y funcionó muy bien.
Edit : Trabajó en API 22 también ...
Aquí está el resultado final.
Nota: El icono es un recurso dibujable en la (s) carpeta (s) dibujable (s).
Ahora aquí está cómo se hace:
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.action_refresh);
Drawable icon = getResources().getDrawable(R.drawable.ic_refresh_white_24dp);
icon.setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN);
item.setIcon(icon);
}
En este punto puedes cambiarlo a cualquier color que quieras!
Otra opción es usar el nuevo soporte para vectores dibujables en la biblioteca de soporte.
Ver res/xml/ic_search.xml
en la entrada del blog AppCompat - Edad de los vectores
Observe la referencia a ?attr/colorControlNormal
<vector xmlns:android="..."
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:pathData="..."
android:fillColor="@android:color/white"/>
</vector>
Simplemente puede crear una barra de herramientas personalizada que use el color del tinte al inflar el menú.
public class MyToolbar extends Toolbar {
... some constructors, extracting mAccentColor from AttrSet, etc
@Override
public void inflateMenu(@MenuRes int resId) {
super.inflateMenu(resId);
Menu menu = getMenu();
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
Drawable icon = item.getIcon();
if (icon != null) {
item.setIcon(applyTint(icon));
}
}
}
void applyTint(Drawable icon){
icon.setColorFilter(
new PorterDuffColorFilter(mAccentColor, PorterDuff.Mode.SRC_IN)
);
}
}
Solo asegúrese de llamar su código de Actividad / Fragmento:
toolbar.inflateMenu(R.menu.some_menu);
toolbar.setOnMenuItemClickListener(someListener);
Sin reflexión, sin vista de búsqueda, y no tanto código, ¿eh?
Y no use onCreateOptionsMenu/onOptionsItemSelected
, si usa este enfoque
Veo que esta pregunta está recibiendo algunas opiniones, así que voy a publicar una respuesta para aquellos que no lean los comentarios.
Mis conjeturas en la pregunta eran todas erróneas y no es una cuestión de canales alfa, al menos no externamente. El hecho es simplemente que, citando a @alanv,
AppCompat solo tiñe sus propios iconos. Por ahora, deberá colorear manualmente los íconos que proporcione por separado de AppCompat.
Esto podría cambiar en el futuro, pero también podría no hacerlo. Desde esta respuesta también puede ver la lista de íconos (todos ellos pertenecen a la carpeta de recursos internos de appcompat, por lo que no puede cambiarlos) que se tiñen automáticamente y con qué color.
Personalmente utilizo un colorControlNormal
que es blanco o negro (o tonos similares), e importo los iconos con ese color en particular. Los iconos de colores sobre un fondo de color se ven un poco mal. Sin embargo, otra solución que encontré agradable es esta clase en github. Simplemente llame a MenuColorizer.colorMenu()
cuando cree el menú.
@NonNull
public static Drawable setTintDrawable(@NonNull Drawable drawable, @ColorInt int color) {
drawable.clearColorFilter();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
drawable.invalidateSelf();
Drawable wrapDrawable = DrawableCompat.wrap(drawable).mutate();
DrawableCompat.setTint(wrapDrawable, color);
return wrapDrawable;
}
y llamar de esta manera:
MenuItem location = menu.findItem(R.id.action_location);
DrawableUtils.setTintDrawable(location.getIcon(), Color.WHITE);