Come modificare il colore del testo della voce di menu in Android?


175

Posso cambiare il colore di sfondo di una voce di menu in Android?

Per favore fatemi sapere se qualcuno ha qualche soluzione a questo. L'ultima opzione sarà ovviamente quella di personalizzarlo, ma esiste un modo per cambiare il colore del testo senza personalizzarlo.


C'è qualcuno che può farmi sapere la soluzione a questo?
domenica

3
vuoi cambiare il colore del testo, il colore di sfondo della vista testo? o entrambi? Entrambe sono cose diverse. Si prega di ri-inquadrare la domanda.
Abhinav Saxena,

Risposte:


335

Una semplice riga nel tuo tema :)

<item name="android:actionMenuTextColor">@color/your_color</item>

19
NOTA: questo DEVE andare nella definizione del tema principale per la tua app, NON all'interno di actionBarStyleper esempio. Non funzionerà all'interno actionBarStyle, anche se sembra logico!
Colin M.,

47
Per supportare versioni API inferiori utilizzare <item name="actionMenuTextColor">@color/your_color</item>non utilizzare lo spazio dei nomi Android
alex.p

5
@ColinM. Deve entrare in un tema. Se si imposta un themeattributo sulla barra degli strumenti, funziona.
Dario

2
Non funzionava per me con o senza Android: namespace. È stato aggiunto al tema dell'app principale.
gareggia il

2
Non riesco ancora a cambiare il colore del testo. Il mio tema generale textcolor prende solo la preferenza. Qualsiasi aiuto? Nessuna di queste risposte funziona.
David P,

114

Sembra che un

  <item name="android:itemTextAppearance">@style/myCustomMenuTextAppearance</item>

nel mio tema e

   <style name="myCustomMenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@android:color/primary_text_dark</item>
    </style>

in styles.xml cambia lo stile delle voci di elenco ma non delle voci di menu.


5
Funziona benissimo per le voci di menu contestuali (non le voci di menu dal pulsante menu) che è quello che stavo cercando. Molto più semplice dell'intero pasticcio LayoutFactory.
Chubbsondubs,

L' android:itemTextAppearanceattributo non può essere inserito in uno stile il cui genitore è parent="@android:style/Widget.Holo.ListPopupWindow"poiché non verrà visualizzato correttamente. Deve essere in uno stile di livello superiore come uno il cui genitore è android:Theme.Holo.Light.DarkActionBar.
toobsco42,

Dove devo aggiungere <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </item>?
Bagusflyer,

@bagusflyer si dovrebbe aggiungere che nello stile root del vostro tema, vale a dire lo stile che è un figlio di Theme.Holoo di Theme.Holo.Light.DarkActionBaro simili.
Tash Pemhiwa,

86

Puoi cambiare MenuItemfacilmente il colore del testo usando SpannableStringinvece di String.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.your_menu, menu);

    int positionOfMenuItem = 0; // or whatever...
    MenuItem item = menu.getItem(positionOfMenuItem);
    SpannableString s = new SpannableString("My red MenuItem");
    s.setSpan(new ForegroundColorSpan(Color.RED), 0, s.length(), 0);
    item.setTitle(s);
}

10
Questo ha funzionato per me sia in 4.4 che in 5+ usando menu.findItem(R.id.menu_item_id);invece dimenu.getItem()
haagmm il

1
Ha funzionato anche per me [usando findItem (...)].
stupito il

6
le soluzioni funzionano solo per l'articolo in overflow .... non voglio cambiare il colore dell'articolo che è visibile impostando showAsAction: "sempre"
Junaid

56

Se stai usando la nuova barra degli strumenti, con il tema Theme.AppCompat.Light.NoActionBar, puoi modellarla nel modo seguente.

 <style name="ToolbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:textColorPrimary">@color/my_color1</item>
    <item name="android:textColorSecondary">@color/my_color2</item>
    <item name="android:textColor">@color/my_color3</item>
 </style>`

Secondo i risultati che ho ottenuto,
android:textColorPrimaryè il colore del testo che mostra il nome della tua attività, che è il testo principale della barra degli strumenti.

android:textColorSecondaryè il colore del testo per i sottotitoli e il pulsante Altre opzioni (3 punti). (Sì, ha cambiato il suo colore in base a questa proprietà!)

android:textColorÈ il colore per tutti gli altri testi incluso il menu.

Infine imposta il tema sulla barra degli strumenti

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:theme="@style/ToolbarTheme"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"/>

Quale elemento regola il testo sui pulsanti mostrati come azioni (testo) sulla barra degli strumenti? Né android: textColorPrimary, android: textColorSecondary, né android: textColor sembra influenzarli.
LarsH,

In risposta alla mia domanda nel commento precedente: android:actionMenuTextColor(vedi stackoverflow.com/a/5538709/423105 ).
LarsH,

32

Se si sta utilizzando il menu come, <android.support.design.widget.NavigationView />basta aggiungere la riga sotto in NavigationView:

app:itemTextColor="your color"

Disponibile anche colorTint per icona, sovrascriverà anche il colore per la tua icona. Per questo devi aggiungere la riga sotto:

app:itemIconTint="your color"

Esempio:

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"

        app:itemTextColor="@color/color_white"
        app:itemIconTint="@color/color_white"

        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"/>

Spero che ti possa aiutare.


Ciò ha modificato gli elementi nidificati in un altro elemento, ma non ha modificato l'elemento contenente altri elementi. Sai come potrei cambiarli anche io?
Dinu Nicolae,

@DinuNicolae Puoi per favore pubblicare il tuo screenshot di esempio? O fornire maggiori dettagli.
Mihir Trivedi

Ho avuto <item> <menu> <oggetti interni> </menu> </item> e solo il colore degli oggetti all'interno è cambiato
Dinu Nicolae

31

L'ho fatto programmaticamente in questo modo:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.changeip_card_menu, menu); 
    for(int i = 0; i < menu.size(); i++) {
        MenuItem item = menu.getItem(i);
        SpannableString spanString = new SpannableString(menu.getItem(i).getTitle().toString());
        spanString.setSpan(new ForegroundColorSpan(Color.BLACK), 0,     spanString.length(), 0); //fix the color to white
        item.setTitle(spanString);
    }
    return true;
}

2
la tua risposta mi ha aiutato a impostare il testo di MenuItem su grassetto. (s.setSpan (nuovo StyleSpan (android.graphics.Typeface.BOLD), 0, s.length (), 0); Grazie!
Arkadiusz Cieśliński

Questa soluzione ha aiutato il mio problema. Mi piace dal momento che non dipenderà dalle condizioni legate al tema.
Tomcat,

15

come puoi vedere in questa domanda dovresti:

<item name="android:textColorPrimary">yourColor</item>

Il codice sopra cambia il colore del testo delle voci di azione del menu per API> = v21.

<item name="actionMenuTextColor">@android:color/holo_green_light</item>

Sopra è il codice per API <v21


Grazie. Questo dovrebbe essere accettato. È semplice e facile
Pooja

10

Ho usato il tag html per cambiare il colore del testo di un singolo elemento quando l'elemento del menu è gonfiato. Spero sarebbe utile.

public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    menu.findItem(R.id.main_settings).setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>"));
    return true;
}

1
Questo non funziona per me su Marshmallow. Il testo viene applicato, ma non il colore.
Ollie C

Per quanto riguarda Marshmallow, probabilmente non funziona per lo stesso motivo indicato nella risposta di max.mustermann, "le soluzioni funzionano solo per gli articoli in overflow".
Jose_GD,

10

Il modo più semplice per rendere il colore del menu personalizzato per la singola barra degli strumenti, non per AppTheme

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay.MenuBlue">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"/>
    </android.support.design.widget.AppBarLayout>

solita barra degli strumenti su styles.xml

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

il nostro stile personalizzato per la barra degli strumenti

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>

Funziona alla grande! Migliore risposta.
Bebe,

9

in Kotlin ho scritto queste estensioni:

fun MenuItem.setTitleColor(color: Int) {
    val hexColor = Integer.toHexString(color).toUpperCase().substring(2)
    val html = "<font color='#$hexColor'>$title</font>"
    this.title = html.parseAsHtml()
}           



@Suppress("DEPRECATION")                                                                        
fun String.parseAsHtml(): Spanned {                                                             
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {                                
        Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)                                         
    } else {                                                                                    
        Html.fromHtml(this)                                                                     
    }                                                                                           
}  

e usato così:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)

Mi piace davvero questa soluzione, molto pulita!
Jamil Nawaz,

Grazie, soluzione semplice e veloce. Per API> 24 funziona senza quella seconda funzione ext
laszlo

7

La risposta breve è SÌ. sei fortunato!
Per fare ciò, è necessario sostituire alcuni stili degli stili predefiniti di Android:

Innanzitutto, guarda la definizione dei temi in Android:

<style name="Theme.IconMenu">
<!-- Menu/item attributes -->
<item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item>
<item name="android:itemBackground">@android:drawable/menu_selector</item>
<item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item>
<item name="android:horizontalDivider">@android:drawable/divider_horizontal_bright</item>
<item name="android:verticalDivider">@android:drawable/divider_vertical_bright</item>
<item name="android:windowAnimationStyle">@android:style/Animation.OptionsPanel</item>
<item name="android:moreIcon">@android:drawable/ic_menu_more</item>
<item name="android:background">@null</item>
</style>

Quindi, l'aspetto del testo nel menu è in @android:style/TextAppearance.Widget.IconMenu.Item
Ora, nella definizione degli stili :

<style name="TextAppearance.Widget.IconMenu.Item" parent="TextAppearance.Small">
<item name="android:textColor">?textColorPrimaryInverse</item>
</style>

Quindi ora abbiamo il nome del colore in questione, se guardi nella cartella dei colori delle risorse del sistema:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@android:color/bright_foreground_light_disabled" /> 
<item android:state_window_focused="false" android:color="@android:color/bright_foreground_light" /> 
<item android:state_pressed="true" android:color="@android:color/bright_foreground_light" /> 
<item android:state_selected="true" android:color="@android:color/bright_foreground_light" /> 
<item android:color="@android:color/bright_foreground_light" /> 
<!--  not selected --> 
</selector>

Infine, ecco cosa devi fare:

Sostituisci "TextAppearance.Widget.IconMenu.Item" e crea il tuo stile. Quindi collegalo al tuo selettore per renderlo come desideri. Spero che questo ti aiuti. In bocca al lupo!


Grazie per la risposta. Ho fatto ciò che mi hai suggerito, ma non cambia il colore della voce di menu
sunil

In realtà, ho appena capito leggendo più cose del menu che è molto più complicato di quanto pensassi Se non vuoi creare il tuo menu personalizzato completo ... Ciò richiederà qualche lettura in più per me, continuerò hai pubblicato qui se ne trovo di più.
Sephy,

Non è possibile sovrascrivere "TextAppearance.Widget.IconMenu.Item".
Peceps,

Questa risposta è fuorviante ... quindi la conclusione è che non funziona ed è molto più difficile / lungo da raggiungere di quanto si pensasse inizialmente?
speedynomads

6

Il menu delle opzioni in Android può essere personalizzato per impostare lo sfondo o modificare l'aspetto del testo. Lo sfondo e il colore del testo nel menu non possono essere modificati utilizzando temi e stili. Il codice sorgente Android (data \ res \ layout \ icon_menu_item_layout.xml) utilizza un elemento personalizzato della classe "com.android.internal.view.menu.IconMenuItem" per il layout del menu. Possiamo apportare modifiche nella classe sopra per personalizzare il menu. Per ottenere lo stesso risultato, utilizzare la classe di fabbrica LayoutInflater e impostare lo sfondo e il colore del testo per la vista.


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);
    getLayoutInflater().setFactory(new Factory() {
        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) {
                try{
                    LayoutInflater f = getLayoutInflater();
                    final View view = f.createView(name, null, attrs);
                    new Handler().post(new Runnable() {
                        public void run() {
                            // set the background drawable
                            view .setBackgroundResource(R.drawable.my_ac_menu_background);

                            // set the text color
                            ((TextView) view).setTextColor(Color.WHITE);
                        }
                    });
                    return view;
                } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {}
            }
            return null;
        }
    });
    return super.onCreateOptionsMenu(menu);
}



3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
A Kra il

Funziona per la prima volta. Quando apri il menu per la seconda volta ottieni un'eccezione.
LoveForDroid l'

6

Grazie per l'esempio di codice. Ho dovuto modificarlo e farlo funzionare con un menu di scelta rapida. Questa è la mia soluzione

    static final Class<?>[] constructorSignature = new Class[] {Context.class, AttributeSet.class};

class MenuColorFix implements LayoutInflater.Factory {
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if (name.equalsIgnoreCase("com.android.internal.view.menu.ListMenuItemView")) {
            try {
                Class<? extends ViewGroup> clazz = context.getClassLoader().loadClass(name).asSubclass(ViewGroup.class);
                Constructor<? extends ViewGroup> constructor = clazz.getConstructor(constructorSignature);
                final ViewGroup view = constructor.newInstance(new Object[]{context,attrs});

                new Handler().post(new Runnable() {
                    public void run() {
                        try {
                            view.setBackgroundColor(Color.BLACK);
                            List<View> children = getAllChildren(view);
                            for(int i = 0; i< children.size(); i++) {
                                View child = children.get(i);
                                if ( child instanceof TextView ) {
                                    ((TextView)child).setTextColor(Color.WHITE);
                                }
                            }
                        }
                        catch (Exception e) {
                            Log.i(TAG, "Caught Exception!",e);
                        }

                    }
                });
                return view;
            }
            catch (Exception e) {
                Log.i(TAG, "Caught Exception!",e);
            }
        }
        return null;
    }       
}

public List<View> getAllChildren(ViewGroup vg) {
    ArrayList<View> result = new ArrayList<View>();
    for ( int i = 0; i < vg.getChildCount(); i++ ) {
        View child = vg.getChildAt(i);
        if ( child instanceof ViewGroup) {
            result.addAll(getAllChildren((ViewGroup)child));
        }
        else {
            result.add(child);
        }
    }
    return result;
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    LayoutInflater lInflater = getLayoutInflater();
    if ( lInflater.getFactory() == null ) {
        lInflater.setFactory(new MenuColorFix());
    }
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.myMenu, menu);
}

Per me questo funziona con Android 1.6, 2.03 e 4.03.


Se stai facendo quanto sopra, dovresti semplicemente guardare usando la soluzione Marcus Wolschon. Molto più semplice
Chubbsondubs,

La soluzione XML non funziona per me, ad esempio su 2.3.x, ma funziona come un incantesimo - anche su 4.x
protezione solare

Questa soluzione ha funzionato al meglio. Ho anche dovuto acquisire android.support.v7.internal.view.menu.ListMenuItemView per ottenere gli stili applicati sui dispositivi usando la libreria di compatibilità
Chiatar

Questa correzione non funzionerà con Google Maps v2 - il metodo super deve essere chiamato 1 ° affinché le mappe vengano visualizzate correttamente.
Chiatar,

5

l'ho trovato Eureka !!

nel tema della tua app:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/ActionBarTheme</item>
    <!-- backward compatibility -->          
    <item name="actionBarStyle">@style/ActionBarTheme</item>        
</style>

ecco il tema della barra delle azioni:

<style name="ActionBarTheme" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
   <item name="android:background">@color/actionbar_bg_color</item>
   <item name="popupTheme">@style/ActionBarPopupTheme</item
   <!-- backward compatibility -->
   <item name="background">@color/actionbar_bg_color</item>
</style>

ed ecco il tuo tema popup:

 <style name="ActionBarPopupTheme">
    <item name="android:textColor">@color/menu_text_color</item>
    <item name="android:background">@color/menu_bg_color</item>
 </style>

Saluti ;)


5

per cambiare il colore del testo della voce di menu utilizzare il codice seguente

<style name="AppToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:itemTextAppearance">@style/menu_item_color</item>
</style>

dove

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>

4

Grazie a max.musterman, questa è la soluzione che ho avuto per lavorare al livello 22:

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchMenuItem = menu.findItem(R.id.search);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setSubmitButtonEnabled(true);
    searchView.setOnQueryTextListener(this);
    setMenuTextColor(menu, R.id.displaySummary, R.string.show_summary);
    setMenuTextColor(menu, R.id.about, R.string.text_about);
    setMenuTextColor(menu, R.id.importExport, R.string.import_export);
    setMenuTextColor(menu, R.id.preferences, R.string.settings);
    return true;
}

private void setMenuTextColor(Menu menu, int menuResource, int menuTextResource) {
    MenuItem item = menu.findItem(menuResource);
    SpannableString s = new SpannableString(getString(menuTextResource));
    s.setSpan(new ForegroundColorSpan(Color.BLACK), 0, s.length(), 0);
    item.setTitle(s);
}

L'hardcoded Color.BLACKpotrebbe diventare un parametro aggiuntivo al setMenuTextColormetodo. Inoltre, l'ho usato solo per le voci di menu che erano android:showAsAction="never".


Non funziona per me su API 24. Qualche idea? Sono stato bloccato su questo per giorni ... ridicolo!
David P,

Non sono sicuro di cosa dirti. Questo funziona bene per me in API 25.
guardiano della luce

3

È possibile impostare il colore a livello di codice.

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

        }
    });
}

3

L'aggiunta di questo nel mio styles.xml ha funzionato per me

<item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>

2

Aggiungi semplicemente questo al tuo tema

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="android:itemTextAppearance">@style/AppTheme.ItemTextStyle</item>
</style>

<style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
        <item name="android:textColor">@color/orange_500</item>
</style>

Testato su API 21


2
È meglio usarlo <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, altrimenti il ​​testo appare troppo piccolo nel menu di overflow. Si noti inoltre che questa tecnica funziona solo su Android 5 e versioni successive.
Mr-IDE,

2
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.search, menu);


    MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
    SearchView searchView = (SearchView) myActionMenuItem.getActionView();

    EditText searchEditText = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchEditText.setTextColor(Color.WHITE); //You color here

1
spiega la tua risposta
Coder

1
E se non fosse un SearchView?
nasch

2

La mia situazione era il colore del testo delle impostazioni nel menu delle opzioni (il menu principale dell'app è mostrato alla pressione del pulsante menu).

Testato in API 16 con la libreria appcompat-v7-27.0.2 , AppCompatActivityper MainActivitye AppCompattema per l'applicazione in AndroidManifest.xml .

styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="actionBarPopupTheme">@style/PopupTheme</item>
</style>

<style name="PopupTheme" parent="@style/ThemeOverlay.AppCompat.Light">
  <item name="android:textColorSecondary">#f00</item>
</style>

Non so se textColorSecondaryinfluisce su altri elementi ma controlla il colore del testo del menu.


Ho cercato alcuni esempi sull'argomento, ma tutti i frammenti pronti all'uso non hanno funzionato.

Quindi volevo investigarlo con il codice sorgente per la libreria appcompat-v7 (in particolare con la cartella res del pacchetto .aar ).

Anche se nel mio caso ho usato Eclipse con dipendenze esplose .aar . Quindi ho potuto cambiare gli stili predefiniti e controllare i risultati. Non so come esplodere le librerie da utilizzare direttamente con Gradle o Android Studio . Merita un altro filo di indagine.

Quindi il mio scopo era quello di trovare quale colore nel file res / valori / valori.xml è usato per il testo del menu (ero quasi sicuro che il colore fosse lì).

  1. Ho aperto quel file, quindi ho duplicato tutti i colori, li ho posizionati sotto quelli predefiniti per sovrascriverli e assegnarli #f00 valore a tutti.
  2. Avvia l'app.
  3. Molti elementi avevano sfondo rosso o colore del testo. E anche le voci di menu. Era quello di cui avevo bisogno.
  4. Rimuovendo i miei colori aggiunti da blocchi di 5-10 linee ho finito con l' secondary_text_default_material_lightelemento colore.
  5. Cercando quel nome nei file all'interno della cartella res (o meglio in res / colors ) ho trovato solo un'occorrenza nel colore / abc_secondary_text_material_light.xml file (ho usato Sublime Text per queste operazioni, quindi è più facile trovare ciò di cui ho bisogno).
  6. Torna ai valori.xml Sono stati trovati 8 usi per@color/abc_secondary_text_material_light .
  7. Era un tema leggero, quindi 4 sono rimasti in 2 temi: Base.ThemeOverlay.AppCompat.LightePlatform.AppCompat.Light .
  8. Il primo tema era figlio del secondo, quindi c'erano solo 2 attributi con quella risorsa colore: android:textColorSecondarye android:textColorTertiarynel file Base.ThemeOverlay.AppCompat.Light.
  9. Modificando i loro valori direttamente in valori.xml ed eseguendo l'app, ho scoperto che l'attributo corretto finale era android:textColorSecondary.
  10. Successivamente avevo bisogno di un tema o di un altro attributo in modo da poterlo modificare in style.xml della mia app (perché il mio tema aveva come genitore il Theme.AppCompat.Lighte non ilThemeOverlay.AppCompat.Light ).
  11. Ho cercato nello stesso file per Base.ThemeOverlay.AppCompat.Light. Aveva un figlioThemeOverlay.AppCompat.Light .
  12. Cercando il ThemeOverlay.AppCompat.Lightho trovato il suo utilizzo nel Base.Theme.AppCompat.Light.DarkActionBartema come ilactionBarPopupTheme valore dell'attributo.
  13. Il tema della mia app Theme.AppCompat.Light.DarkActionBarera figlio del trovato, Base.Theme.AppCompat.Light.DarkActionBarquindi ho potuto usare quell'attributo nel mio styles.xml senza problemi.
  14. Come si vede nel codice di esempio sopra ho creato un tema figlio dal menzionato ThemeOverlay.AppCompat.Lighte modificato l' android:textColorSecondaryattributo.

https://i.imgur.com/LNfKdzC.png


1

La soluzione di Sephy non funziona. È possibile sovrascrivere l'aspetto del testo della voce di menu delle opzioni utilizzando il metodo sopra descritto, ma non l'elemento o il menu. Per farlo ci sono essenzialmente 3 modi:

  1. Come modificare il colore di sfondo del menu delle opzioni?
  2. Scrivi la tua vista per visualizzare e sovrascrivere onCreateOptionsMenu e onPrepareOptionsMenu per ottenere i risultati desiderati. Lo dico in generale perché generalmente puoi fare quello che vuoi in questi metodi, ma probabilmente non vorrai chiamare in super ().
  3. Copia il codice dall'SDK open-source e personalizzalo per il tuo comportamento. L'implementazione del menu predefinita utilizzata da Activity non verrà più applicata.

Vedere il numero 4441: tema del menu Opzioni personalizzate per ulteriori indizi.


Per ribadire ... La soluzione di Sephy funziona per la voce di menu TextAppearance, anche se quello che ho fatto è sovrascrivere il valore predefinito tramite themes.xml. Inoltre, # 2 o # 3 sopra dovrebbero essere consapevoli del fatto che la chiamata a super # onCreateOptionsMenu / super # onPrepareOptionsMenu è progettata per posizionare voci di menu di sistema ... come indicato nel javadoc per Activity # onCreateOptionsMenu (). Ciò potrebbe / potrebbe non essere importante per la tua app.
Tenace

Ciò che Sephy sta descrivendo è di avere questo nel vostro themes.xml: <nome oggetto = "android: itemTextAppearance"> @ style / Text_MenuItemText </item> Quindi definire qualcosa di simile nel vostro styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </item> <item name = "android: textColor"> # FFFFFF </item> </style> È facile come si arriva. Era quello che intendevi? La personalizzazione del menu delle opzioni più approfondita non è affatto facile, ma ho intenzione di pubblicare presto un articolo sul blog.
Tenace

1

prova questo codice ....

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.my_menu, menu);

        getLayoutInflater().setFactory(new Factory() {
            @Override
            public View onCreateView(String name, Context context,
                    AttributeSet attrs) {

                if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
                    try {
                        LayoutInflater f = getLayoutInflater();
                        final View view = f.createView(name, null, attrs);

                        new Handler().post(new Runnable() {
                            public void run() {

                                // set the background drawable
                                 view.setBackgroundResource(R.drawable.my_ac_menu_background);

                                // set the text color
                                ((TextView) view).setTextColor(Color.WHITE);
                            }
                        });
                        return view;
                    } catch (InflateException e) {
                    } catch (ClassNotFoundException e) {
                    }
                }
                return null;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }

1
su Android> 4.0 sto arrivandojava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
A Kra il

1

Se si desidera impostare il colore per una singola voce di menu, la personalizzazione di un tema della barra degli strumenti non è la soluzione giusta. Per raggiungere questo obiettivo, puoi utilizzare Android: actionLayout e una vista azione per la voce di menu.

Innanzitutto creare un file di layout XML per la vista azioni. In questo esempio utilizziamo un pulsante come vista di azione:

menu_button.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/menuButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Done"
        android:textColor="?android:attr/colorAccent"
        style="?android:attr/buttonBarButtonStyle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Nello snippet di codice sopra, usiamo android:textColor="?android:attr/colorAccent"per personalizzare il colore del testo del pulsante.

Quindi nel file di layout XML per il menu, includere app:actionLayout="@layout/menu_button"come mostrato di seguito:

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/menuItem"
        android:title=""
        app:actionLayout="@layout/menu_button"
        app:showAsAction="always"/>
</menu>

Ultima modifica del onCreateOptionsMenu()metodo nella tua attività:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    saveButton.setOnClickListener(view -> {
        // Do something
    });
    return true;
}

... o frammento:

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater){
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem item = menu.findItem(R.id.menuItem);
    Button saveButton = item.getActionView().findViewById(R.id.menuButton);
    button.setOnClickListener(view -> {
        // Do something
    });
}

Per ulteriori dettagli sulle visualizzazioni delle azioni, consultare la guida per sviluppatori Android .


0

Ecco come è possibile colorare una voce di menu specifica con il colore, funziona per tutti i livelli API:

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

In questo modo perdi l'effetto del selettore di sfondo, quindi ecco il codice per applicare un selettore di sfondo personalizzato a tutti gli elementi del menu figlio.

public static void setToolbarMenuItemsBackgroundSelector(final Context context,
                                                         final Toolbar toolbar) {
    if (toolbar != null) {
        for (int i = 0; i < toolbar.getChildCount(); i++) {
            final View view = toolbar.getChildAt(i);
            if (view instanceof ImageButton) {
                // left toolbar icon (navigation, hamburger, ...)
                UiHelper.setViewBackgroundSelector(context, view);
            } else 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) {
                                // text item views
                                final ActionMenuItemView itemView = (ActionMenuItemView) innerView;
                                UiHelper.setViewBackgroundSelector(context, itemView);

                                // icon item views
                                for (int k = 0; k < itemView.getCompoundDrawables().length; k++) {
                                    if (itemView.getCompoundDrawables()[k] != null) {
                                        UiHelper.setViewBackgroundSelector(context, itemView);
                                    }
                                }
                            }
                        }
                    }
                });
            }
        }
    }
}

Ecco anche la funzione di aiuto:

public static void setViewBackgroundSelector(@NonNull Context context, @NonNull View itemView) {
    int[] attrs = new int[]{R.attr.selectableItemBackgroundBorderless};
    TypedArray ta = context.obtainStyledAttributes(attrs);
    Drawable drawable = ta.getDrawable(0);
    ta.recycle();

    ViewCompat.setBackground(itemView, drawable);
}

0

Per cambiare il colore del testo, puoi semplicemente impostare una vista personalizzata per MenuItem, quindi puoi definire il colore per il testo.

Codice di esempio: MenuItem.setActionView ()


Mentre questo frammento di codice può risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
Mischa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.