Cambiare MenuItem colore del text in modo programmato

Quindi ho una voce di menu, che è definita come:

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

Esso mostra come text, come si può vedere di seguito:

  • Compressione di texture di Android OpenGL
  • Impostare GIF animato come background Android
  • Qual è la differenza tra una window di dialogo che viene rimossa o annullata in Android?
  • "Memorizzazione insufficiente disponibile" anche in memory è molto spazio libero
  • Combina immagini in android
  • Prendi le chiavi di arrays di json in android
  • Schermata 1

    E voglio modificare in modo programmale il colore del text "LIVE". Ho cercato un po 'e ho trovato un metodo:

    Con definizione globale:

     private Menu mOptionsMenu; 

    e:

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

    Lo voglio:

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

    Ma non succede niente!

    Se faccio lo stesso per un elemento del menu di overflow, funziona:

    Schermata 2

    C'è qualche limitazione per gli oggetti app: showAsAction = "ifRoom | withText"? C'è qualche soluzione?

    Grazie in anticipo.

  • Utilizzo di sendBroadcast ()
  • Come sapere il momento in cui la persona chiamata prende il suo telefono
  • Multicast su Android 2.2
  • perché marginBottom non funziona?
  • Aggiunta di viste al figlio in un layout relativo
  • Perché dovrei utilizzare il frammento in Android?
  • 4 Solutions collect form web for “Cambiare MenuItem colore del text in modo programmato”

    Un po 'tardi per la festa con questo, ma ho passato un po' a lavorare su questo e ho trovato una soluzione che potrebbe essere utile per chiunque altro cerca di fare la stessa cosa. Qualche credito va a Harish Sridharan per guidarmi nella giusta direzione.

    È ansible utilizzare findViewById(R.id.MY_MENU_ITEM_ID) per individuare la voce di menu (a condizione che il menu sia stato creato e preparato) e lanciarlo in un'istanza di TextView come suggerito da Harish, che può essere personalizzato come richiesto.

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

    }

    Il trucco qui è quello di costringere il menu a essere invalidato nell'evento onCreate dell'attività (causando quindi che onPrepareMenuOptions venga chiamata prima di quanto normalmente). All'interno di questo metodo, possiamo individuare la voce di menu e lo stile come richiesto.

    Diventa solo una visione di text dopo l'ispezione, la sua vera class è ActionMenuItemView, su cui possiamo ulteriormente impostare il colore del text come questo:

     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 mi dà un indizio, ma la sua soluzione non funziona per me. E @ Box danno un'altra, ma la sua risposta sembra un po 'less pulita. Grazie a loro. Quindi, secondo loro, ho una soluzione totale.

     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); } } }); } 

    MenuItem come definito dalla documentazione è un'interface. Sarà sicuramente implementato con un widget di visualizzazione prima di essere rappresentato come menu. Nella maggior parte dei casi queste voci di menu vengono implementate come TextView. È ansible utilizzare UiAutomatorViewer per visualizzare la gerarchia delle visualizzazioni o addirittura utilizzare gerarchyviewer che si trova in [sdk-home] / tools /. Ha allegato un esempio di screenshot uiautomatorviewer per un MenuItem

    Quindi puoi sempre digitare il tuo MenuItem e impostare il colore.

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

    EDIT:

    Poiché vi era richiesta di vedere come utilizzare questo strumento, aggiungo un po 'di contenuti.

    Assicurati di aver impostato la variabile d'ambiente $ ANDROID_HOME che indica la tua SDK HOME.

    Nel tuo terminal:

     cd $ANDROID_HOME ./tools/uiautomatorviewer 

    Questo strumento si aprirà.

    Il secondo o il terzo button (fare riferimento alla schermata) nel menu catturerà lo screenshot del dispositivo o dell'emulatore collegato e puoi controllare la visualizzazione e la loro gerarchia. Cliccando sulla visualizzazione verrà descritta la vista e le relative informazioni. È strumento progettato appositamente per il test e si può verificare qualsiasi applicazione.

    Fare riferimento allo sviluppatore per ulteriori informazioni: uiautomatorviewer

    uiautomatorviewer

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.