studio how example custom boton bar agregar android android-actionbar

example - show action bar android



Cambiar el color de texto del elemento de menú mediante programación (4)

MenuItem según lo definido por la documentación es una interfaz. Definitivamente se implementará con un widget de vista antes de ser retratado como un menú. La mayoría de los casos, estos elementos del menú se implementan como TextView. Puede usar UiAutomatorViewer para ver la jerarquía de vistas o incluso usar hierarchyviewer que se encontrará en [sdk-home] / tools /. Se adjuntó una captura de pantalla de uiautomatorviewer de muestra para un MenuItem

Por lo tanto, siempre puede encasillar su MenuItem y establecer el color.

TextView liveitem = (TextView)mOptionsMenu.findItem(R.id.action_live); liveitem.setTextColor(Color.RED);

EDITAR:

Como hubo una solicitud para ver cómo usar esta herramienta, estoy agregando algunos contenidos más.

Asegúrese de haber configurado la variable de entorno $ ANDROID_HOME apuntando a su SDK HOME.

En tu terminal:

cd $ANDROID_HOME ./tools/uiautomatorviewer

Esta herramienta se abrirá.

El segundo o tercer botón (consulte la captura de pantalla) en el menú capturará la captura de pantalla de su dispositivo o emulador conectado y podrá inspeccionar la vista y su jerarquía. Al hacer clic en la vista, se describirá la vista y su información. Es una herramienta diseñada a propósito para las pruebas y puede inspeccionar cualquier aplicación.

Consulte el sitio del desarrollador para obtener más información: uiautomatorviewer

Así que tengo un elemento de menú, que se define como:

<item android:id="@+id/action_live" android:title="@string/action_live" android:orderInCategory="1" app:showAsAction="ifRoom|withText" />

Se muestra como texto, como puedes ver a continuación:

Y quiero cambiar programáticamente el color de texto "EN VIVO". He buscado por un tiempo y encontré un método:

Con globalmente definido:

private Menu mOptionsMenu;

y:

@Override public boolean onCreateOptionsMenu(Menu menu) { mOptionsMenu = menu; getMenuInflater().inflate(R.menu.menu_main, menu); return true; }

Hago:

MenuItem liveitem = mOptionsMenu.findItem(R.id.action_live); SpannableString s = new SpannableString(liveitem.getTitle().toString()); s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0); liveitem.setTitle(s);

¡Pero nada pasa!

Si hago lo mismo con un elemento del menú de desbordamiento, funciona:

¿Existe alguna limitación para los elementos de la aplicación: showAsAction = "ifRoom | withText"? ¿Hay algún trabajo alrededor?

Gracias por adelantado.


Llegué un poco tarde a la fiesta con esta, pero pasé un tiempo trabajando en esto y encontré una solución, que puede ser útil para cualquier otra persona que intente hacer lo mismo. Algo de crédito va para Harish Sridharan por dirigirme en la dirección correcta.

Puede usar findViewById(R.id.MY_MENU_ITEM_ID) para ubicar el elemento del menú (siempre que el menú haya sido creado y preparado), y TextView a una instancia de TextView como lo sugiere Harish, que luego se puede diseñar según sea necesario.

public class MyAwesomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { getWindow().requestFeature(Window.FEATURE_ACTION_BAR); super.onCreate(savedInstanceState); // Force invalidatation of the menu to cause onPrepareOptionMenu to be called invalidateOptionsMenu(); } private void styleMenuButton() { // Find the menu item you want to style View view = findViewById(R.id.YOUR_MENU_ITEM_ID_HERE); // Cast to a TextView instance if the menu item was found if (view != null && view instanceof TextView) { ((TextView) view).setTextColor( Color.BLUE ); // Make text colour blue ((TextView) view).setTextSize(TypedValue.COMPLEX_UNIT_SP, 24); // Increase font size } } @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean result = super.onPrepareOptionsMenu(menu); styleMenuButton(); return result; }

}

El truco aquí es forzar la invalidación del menú en el evento onCreate la actividad (lo que hace que onPrepareMenuOptions se llame antes de lo normal). Dentro de este método, podemos ubicar el elemento y el estilo del menú según sea necesario.


Solo se convierte en una vista de texto después de la inspección, su clase real es ActionMenuItemView, en la que podemos configurar el color del texto de esta manera:

public static void setToolbarMenuItemTextColor(final Toolbar toolbar, final @ColorRes int color, @IdRes final int resId) { if (toolbar != null) { for (int i = 0; i < toolbar.getChildCount(); i++) { final View view = toolbar.getChildAt(i); if (view instanceof ActionMenuView) { final ActionMenuView actionMenuView = (ActionMenuView) view; // view children are accessible only after layout-ing actionMenuView.post(new Runnable() { @Override public void run() { for (int j = 0; j < actionMenuView.getChildCount(); j++) { final View innerView = actionMenuView.getChildAt(j); if (innerView instanceof ActionMenuItemView) { final ActionMenuItemView itemView = (ActionMenuItemView) innerView; if (resId == itemView.getId()) { itemView.setTextColor(ContextCompat.getColor(toolbar.getContext(), color)); } } } } }); } } } }


@RRP dame una pista, pero su solución no funciona para mí. Y @Box se dan mutuamente, pero su respuesta se ve un poco menos clara. Gracias ellos. Entonces, según ellos, tengo una solución total.

private static void setMenuTextColor(final Context context, final Toolbar toolbar, final int menuResId, final int colorRes) { toolbar.post(new Runnable() { @Override public void run() { View settingsMenuItem = toolbar.findViewById(menuResId); if (settingsMenuItem instanceof TextView) { if (DEBUG) { Log.i(TAG, "setMenuTextColor textview"); } TextView tv = (TextView) settingsMenuItem; tv.setTextColor(ContextCompat.getColor(context, colorRes)); } else { // you can ignore this branch, because usually there is not the situation Menu menu = toolbar.getMenu(); MenuItem item = menu.findItem(menuResId); SpannableString s = new SpannableString(item.getTitle()); s.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, colorRes)), 0, s.length(), 0); item.setTitle(s); } } }); }