Wie ändere ich die Textfarbe des Menüelements in Android?

175

Kann ich die Hintergrundfarbe eines Menüelements in Android ändern?

Bitte lassen Sie mich wissen, wenn jemand eine Lösung dafür hat. Die letzte Option ist natürlich das Anpassen, aber es gibt eine Möglichkeit, die Textfarbe zu ändern, ohne sie anzupassen.

sunil
quelle
Gibt es jemanden, der mir die Lösung dafür mitteilen kann?
Sunil
3
Möchten Sie die Textfarbe und die Hintergrundfarbe der Textansicht ändern? oder beides? Beides sind verschiedene Dinge. Bitte rahmen Sie die Frage neu ein.
Abhinav Saxena

Antworten:

335

Eine einfache Zeile in Ihrem Thema :)

<item name="android:actionMenuTextColor">@color/your_color</item>
Muhammad Alfaifi
quelle
19
HINWEIS: Dies MUSS in der Hauptthema-Definition für Ihre App enthalten sein, NICHT actionBarStylebeispielsweise in der. Es wird innen nicht funktionieren actionBarStyle, obwohl das logisch erscheint!
Colin M.
47
Verwenden <item name="actionMenuTextColor">@color/your_color</item>Sie zur Unterstützung niedrigerer API-Versionen nicht den Android-Namespace
alex.p
5
@ColinM. Es muss in ein Thema gehen. Wenn Sie in themeIhrer Symbolleiste ein Attribut festlegen , funktioniert dies.
DariusL
2
Funktionierte bei mir weder mit noch ohne android: namespace. Es wurde dem Haupt-App-Thema hinzugefügt.
Rennen
2
Ich kann die Textfarbe immer noch nicht ändern. Mein allgemeines Thema Textfarbe bevorzugt nur. Irgendeine Hilfe? Keine dieser Antworten funktioniert.
David P
114

Es scheint, dass ein

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

in meinem Thema und

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

Ändern Sie in styles.xml den Stil von Listenelementen, jedoch nicht von Menüelementen.

Marcus Wolschon
quelle
5
Dies funktioniert hervorragend für Kontextmenüelemente (nicht für Menüelemente über die Menüschaltfläche), nach denen ich gesucht habe. Viel einfacher als das ganze LayoutFactory-Chaos.
Chubbsondubs
Das android:itemTextAppearanceAttribut kann nicht in einem Stil platziert werden, dessen übergeordnetes Element vorhanden ist, parent="@android:style/Widget.Holo.ListPopupWindow"da dies nicht ordnungsgemäß gerendert wird. Es muss in einem Top-Level-Stil sein, wie einer, dessen Eltern sind android:Theme.Holo.Light.DarkActionBar.
toobsco42
Wo soll ich <item name = "android: itemTextAppearance"> @ style / myCustomMenuTextApearance </ item> hinzufügen?
Bagusflyer
@bagusflyer sollten Sie , dass im Stamm Stil Ihres Themas hinzufügen, also den Stil, der ein Kind ist Theme.Holooder Theme.Holo.Light.DarkActionBaroder ähnliches.
Tash Pemhiwa
86

Sie können die Farbe des MenuItemTextes einfach ändern, indem Sie SpannableStringanstelle von verwenden 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);
}
max.mustermann
quelle
10
Das ist für mich arbeitete sowohl in 4.4 und 5+ mit menu.findItem(R.id.menu_item_id);stattmenu.getItem()
haagmm
1
Hat auch für mich funktioniert [mit findItem (...)].
benommen
6
Lösungen funktionieren nur für Artikel im Überlauf .... Ich möchte die Artikelfarbe nicht ändern, die durch Setzen von showAsAction sichtbar wird: "immer"
Junaid
56

Wenn Sie die neue Symbolleiste mit dem Thema verwenden Theme.AppCompat.Light.NoActionBar, können Sie sie folgendermaßen formatieren.

 <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>`

Nach den Ergebnissen, die ich erhalten habe,
android:textColorPrimaryzeigt die Textfarbe den Namen Ihrer Aktivität an, der der Haupttext der Symbolleiste ist.

android:textColorSecondaryist die Textfarbe für Untertitel und weitere Optionen (3 Punkte). (Ja, es hat seine Farbe entsprechend dieser Eigenschaft geändert!)

android:textColorIst die Farbe für alle anderen Texte einschließlich des Menüs.

Stellen Sie das Thema schließlich auf die Symbolleiste ein

<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"/>
Sudara
quelle
Welches Element regelt den Text auf den Schaltflächen, die in der Symbolleiste als Aktionen (Text) angezeigt werden? Weder android: textColorPrimary, android: textColorSecondary noch android: textColor scheinen sie zu beeinflussen.
LarsH
Als Antwort auf meine Frage im vorhergehenden Kommentar: android:actionMenuTextColor(siehe stackoverflow.com/a/5538709/423105 ).
LarsH
31

Wenn Sie das Menü als verwenden, <android.support.design.widget.NavigationView />fügen Sie einfach die folgende Zeile hinzu NavigationView:

app:itemTextColor="your color"

Ebenfalls als colorTint für Symbol verfügbar, überschreibt es auch die Farbe für Ihr Symbol. Dazu müssen Sie folgende Zeile hinzufügen:

app:itemIconTint="your color"

Beispiel:

<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"/>

Hoffe es wird dir helfen.

Mihir Trivedi
quelle
Dadurch wurden die Elemente geändert, die in einem anderen Element verschachtelt sind, das Element, das andere Elemente enthält, wurde jedoch nicht geändert. Weißt du, wie ich sie auch ändern könnte?
Dinu Nicolae
@DinuNicolae Kannst du bitte deinen Beispiel-Screenshot posten? Oder geben Sie mehr Details an.
Mihir Trivedi
Ich hatte <item> <menu> <inside items> </ menu> </ item> und nur die Farbe der darin enthaltenen Elemente hat sich geändert
Dinu Nicolae
31

Ich habe es programmatisch so gemacht:

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;
}
Muralikrishna GS
quelle
2
Ihre Antwort hat mir geholfen, den MenuItem-Text fett zu setzen. (s.setSpan (neues StyleSpan (android.graphics.Typeface.BOLD), 0, s.length (), 0); Danke!
Arkadiusz Cieśliński
Diese Lösung hat meinem Problem geholfen. Ich mag das, da es nicht von themenbezogenen Bedingungen abhängt.
Tomcat
15

Wie Sie in dieser Frage sehen können , sollten Sie:

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

Der obige Code ändert die Textfarbe der Menüaktionselemente für API> = v21.

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

Oben ist der Code für API <v21

Pouya Danesh
quelle
Danke dir. Dies sollte akzeptiert werden. Es ist einfach und leicht
Pooja
10

Ich habe das HTML-Tag verwendet, um die Textfarbe eines einzelnen Elements zu ändern, wenn das Menüelement aufgeblasen wird. Hoffe es wäre hilfreich.

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;
}
Alijandro
quelle
1
Bei Marshmallow funktioniert das bei mir nicht. Der Text wird angewendet, aber nicht die Farbe.
Ollie C
In Bezug auf Marshmallow funktioniert es wahrscheinlich nicht aus dem gleichen Grund, der in der Antwort von max.mustermann angegeben ist: "Lösungen funktionieren nur für Artikel im Überlauf."
Jose_GD
10

EINFACHSTE Möglichkeit, benutzerdefinierte Menüfarben für eine einzelne Symbolleiste und nicht für AppTheme zu erstellen

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

übliche Symbolleiste auf styles.xml

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

unser benutzerdefinierter Symbolleistenstil

<style name="AppTheme.AppBarOverlay.MenuBlue">
    <item name="actionMenuTextColor">@color/blue</item>
</style>
AndrewS
quelle
Funktioniert super! Beste Antwort.
Bebe
9

In Kotlin habe ich folgende Erweiterungen geschrieben:

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

und so verwendet:

menu.findItem(R.id.main_settings).setTitleColor(Color.RED)
Amir Khorsandi
quelle
Mag diese Lösung wirklich, sehr ordentlich!
Jamil Nawaz
Danke, einfache und schnelle Lösung. Für API> 24 funktioniert es ohne diese zweite ext-Funktion
laszlo
7

Die kurze Antwort lautet JA. Du Glückspilz!
Dazu müssen Sie einige Stile der Android-Standardstile überschreiben:

Schauen Sie sich zunächst die Definition der Themen in Android an:

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

Das Erscheinungsbild des Textes im Menü befindet sich also @android:style/TextAppearance.Widget.IconMenu.Item
in der Definition der Stile in Jetzt :

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

Jetzt haben wir also den Namen der betreffenden Farbe, wenn Sie im Farbordner der Ressourcen des Systems nachsehen:

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

Zum Schluss müssen Sie Folgendes tun:

Überschreiben Sie "TextAppearance.Widget.IconMenu.Item" und erstellen Sie Ihren eigenen Stil. Verknüpfen Sie es dann mit Ihrem eigenen Selektor, um es so zu gestalten, wie Sie es möchten. Hoffe das hilft dir. Viel Glück!

Sephy
quelle
Danke für Ihre Antwort. Ich habe getan, was Sie vorgeschlagen haben, aber es ändert nicht die Farbe des Menüpunktes
sunil
Eigentlich habe ich gerade durch das Lesen von mehr Menüpunkten festgestellt, dass es viel komplizierter ist als ich dachte. Wenn Sie kein eigenes benutzerdefiniertes Menü erstellen möchten ... Dies erfordert mehr Lesen für mich, ich werde es behalten Sie haben hier gepostet, wenn ich mehr finde.
Sephy
"TextAppearance.Widget.IconMenu.Item" kann nicht überschrieben werden.
Peceps
Diese Antwort ist irreführend. Die Schlussfolgerung lautet also, dass sie nicht funktioniert und viel schwieriger / langwieriger zu erreichen ist als ursprünglich angenommen.
Speedynomads
6

Das Optionsmenü in Android kann angepasst werden, um den Hintergrund festzulegen oder das Erscheinungsbild des Textes zu ändern. Der Hintergrund und die Textfarbe im Menü konnten mithilfe von Themen und Stilen nicht geändert werden. Der Android-Quellcode (data \ res \ layout \ icon_menu_item_layout.xml) verwendet ein benutzerdefiniertes Element der Klasse "com.android.internal.view.menu.IconMenuItem" View für das Menülayout. Wir können Änderungen in der obigen Klasse vornehmen, um das Menü anzupassen. Verwenden Sie dazu die Factory-Klasse LayoutInflater und legen Sie den Hintergrund und die Textfarbe für die Ansicht fest.


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


Abhay Kumar
quelle
3
03-23 19:45:25.134: E/AndroidRuntime(26761): java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
Zu Kra
Dies funktioniert zum ersten Mal. Wenn Sie das Menü zum zweiten Mal öffnen, erhalten Sie eine Ausnahme.
LoveForDroid
6

Danke für das Codebeispiel. Ich musste es ändern, damit es mit einem Kontextmenü funktioniert. Das ist meine Lösung.

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

Bei mir funktioniert das mit Android 1.6, 2.03 und 4.03.

Michael Vogl
quelle
Wenn Sie das oben genannte tun, sollten Sie sich nur die Verwendung der Marcus Wolschon-Lösung ansehen. Viel einfacher.
Chubbsondubs
Die XML-Lösung funktioniert nicht für mich auf zB 2.3.x, aber dies funktioniert wie ein Zauber - auch auf 4.x
Sunlock
Diese Lösung hat am besten funktioniert. Ich musste auch android.support.v7.internal.view.menu.ListMenuItemView erfassen, um die Stile auf Geräte mit der Kompatibilitätsbibliothek
anzuwenden
Dieser Fix funktioniert nicht mit Google Maps v2 - die Supermethode muss als 1. bezeichnet werden, damit die Karten korrekt gerendert werden.
Chiatar
5

Ich fand es Eureka !!

in Ihrem App-Thema:

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

Hier ist Ihr Action-Bar-Thema:

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

und hier ist dein Popup-Thema:

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

Prost ;)

Fareed Alnamrouti
quelle
5

Um die Textfarbe des Menüelements zu ändern, verwenden Sie den folgenden Code

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

wo

<style name="menu_item_color">
<item name="android:textColor">@color/app_font_color</item>
</style>
Muhammad Abdullah
quelle
4

Dank max.musterman ist dies die Lösung, mit der ich in Level 22 arbeiten konnte:

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

Das Hardcodierte Color.BLACKkönnte ein zusätzlicher Parameter für die setMenuTextColorMethode werden. Außerdem habe ich dies nur für Menüpunkte verwendet, die waren android:showAsAction="never".

Lichthüter
quelle
Ich arbeite nicht für API 24. Irgendwelche Ideen? Ich bin schon seit Tagen dabei ... lächerlich!
David P
Ich bin mir nicht sicher, was ich dir sagen soll. Dies funktioniert gut für mich in API 25.
Lightkeeper
3

Sie können die Farbe programmgesteuert einstellen.

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

        }
    });
}
Victor Choy
quelle
3

Das Hinzufügen zu meiner styles.xml hat bei mir funktioniert

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

Fügen Sie dies einfach Ihrem Thema hinzu

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

Getestet auf API 21

Pham Quan
quelle
2
Es ist besser zu verwenden <style name="AppTheme.ItemTextStyle" parent="@android:style/TextAppearance.Widget">, sonst erscheint der Text im Überlaufmenü zu klein. Beachten Sie auch, dass diese Technik nur unter Android 5 und höher funktioniert.
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
Bäda
quelle
1
Erklären Sie Ihre Antwort
Coder
1
Was ist, wenn es sich nicht um eine Suchansicht handelt?
Nasch
2

Meine Situation war die Einstellung der Textfarbe im Optionsmenü (das Hauptmenü der App wurde beim Drücken der Menütaste angezeigt).

Getestet in API 16 mit der Bibliothek appcompat-v7-27.0.2AppCompatActivity für MainActivityund AppCompatThema für die Anwendung 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>

Ich weiß nicht, ob dies textColorSecondaryandere Elemente betrifft, aber es steuert die Menütextfarbe.


Ich habe einige Beispiele zu diesem Thema durchsucht, aber alle gebrauchsfertigen Snippets haben nicht funktioniert.

Deshalb wollte ich es mit dem Quellcode für die appcompat-v7- Bibliothek untersuchen (speziell mit dem res- Ordner des .aar- Pakets).

In meinem Fall habe ich Eclipse mit explodierten .aar- Abhängigkeiten verwendet. So konnte ich die Standardstile ändern und die Ergebnisse überprüfen. Ich weiß nicht, wie ich die Bibliotheken für Gradle oder Android Studio auflösen soll direkt . Es verdient einen weiteren Untersuchungsfaden.

Mein Ziel war es also herauszufinden, welche Farbe in der Datei res / values ​​/ values.xml für den Menütext verwendet wird (ich war mir fast sicher, dass die Farbe vorhanden war).

  1. Ich habe diese Datei geöffnet, dann alle Farben dupliziert und sie unter die Standardfarben gesetzt, um sie zu überschreiben und zuzuweisen #f00 allen einen Wert .
  2. Starten Sie die App.
  3. Viele Elemente hatten einen roten Hintergrund oder eine rote Textfarbe. Und die Menüpunkte auch. Das brauchte ich.
  4. Nachdem ich meine hinzugefügten Farben durch Blöcke von 5 bis 10 Zeilen entfernt hatte, endete ich mit dem secondary_text_default_material_lightFarbelement.
  5. Bei der Suche nach diesem Namen in den Dateien im Ordner res (oder besser in res / colours ) wurde nur ein Vorkommen in der Datei color / abc_secondary_text_material_light.xml gefunden Datei (ich habe Sublime Text für diese Vorgänge verwendet, damit ich leichter das finden kann, was ich brauche).
  6. Zurück zur Datei values.xml wurden 8 Verwendungen für die gefunden@color/abc_secondary_text_material_light .
  7. Es war ein Lichtthema, also blieben 4 in 2 Themen: Base.ThemeOverlay.AppCompat.LightundPlatform.AppCompat.Light .
  8. Das erste Thema war ein Kind des zweiten, daher gab es nur zwei Attribute mit dieser Farbressource: android:textColorSecondaryund android:textColorTertiaryin der Base.ThemeOverlay.AppCompat.Light.
  9. Als ich ihre Werte direkt in der Datei values.xml änderte und die App ausführte , stellte ich fest, dass das endgültige richtige Attribut war android:textColorSecondary.
  10. Als nächstes brauchte ich ein Thema oder ein anderes Attribut, damit ich es in der style.xml meiner App ändern konnte (weil mein Thema als übergeordnetes Element das Theme.AppCompat.Lightund nicht das hatte ThemeOverlay.AppCompat.Light).
  11. Ich habe in derselben Datei nach dem gesucht Base.ThemeOverlay.AppCompat.Light. Es hatte ein Kind ThemeOverlay.AppCompat.Light.
  12. Bei der Suche nach dem habe ThemeOverlay.AppCompat.Lightich seine Verwendung im Base.Theme.AppCompat.Light.DarkActionBarThema als actionBarPopupThemeAttributwert gefunden.
  13. Das Thema meiner App Theme.AppCompat.Light.DarkActionBarwar ein untergeordnetes Element des gefundenen, Base.Theme.AppCompat.Light.DarkActionBarsodass ich dieses Attribut in meiner styles.xml verwenden konnte verwenden konnte.
  14. Wie im obigen Beispielcode zu sehen ist, habe ich aus dem genannten ein untergeordnetes Thema erstellt ThemeOverlay.AppCompat.Lightund das android:textColorSecondaryAttribut geändert .

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

mortalis
quelle
1

Sephys Lösung funktioniert nicht. Es ist möglich, das Erscheinungsbild des Optionsmenüelements mit der oben beschriebenen Methode zu überschreiben, jedoch nicht mit dem Element oder Menü. Dazu gibt es im Wesentlichen drei Möglichkeiten:

  1. Wie ändere ich die Hintergrundfarbe des Optionsmenüs?
  2. Schreiben Sie Ihre eigene Ansicht, um onCreateOptionsMenu und onPrepareOptionsMenu anzuzeigen und zu überschreiben, um die gewünschten Ergebnisse zu erhalten. Ich sage dies allgemein, weil Sie mit diesen Methoden im Allgemeinen tun können, was Sie wollen, aber Sie werden wahrscheinlich nicht in super () aufrufen wollen.
  3. Kopieren Sie den Code aus dem Open Source SDK und passen Sie ihn an Ihr Verhalten an. Die von Activity verwendete Standardmenüimplementierung gilt nicht mehr.

Weitere Hinweise finden Sie in Ausgabe 4441: Menü "Benutzerdefinierte Optionen" .

Zäh
quelle
Um es noch einmal zu wiederholen ... Sephys Lösung funktioniert für den Menüpunkt TextAppearance. Ich habe jedoch die Standardeinstellung durch eine theme.xml überschrieben. Außerdem sollte # 2 oder # 3 oben beachten, dass das Aufrufen von super # onCreateOptionsMenu / super # onPrepareOptionsMenu zum Platzieren von Systemmenüelementen dient ... wie im Javadoc für Aktivität # onCreateOptionsMenu () angegeben. Das kann / kann für Ihre App nicht wichtig sein.
Hartnäckig
Was Sephy beschreibt, ist, dies in Ihrer theme.xml zu haben: <item name = "android: itemTextAppearance"> @ style / Text_MenuItemText </ item> Definieren Sie dann so etwas in Ihrer styles.xml: <style name = "Text_MenuItemText" > <item name = "android: textSize"> 12dp </ item> <item name = "android: textColor"> # FFFFFF </ item> </ style> Das ist so einfach wie es nur geht. War es das was du meintest? Eine tiefere Anpassung des Optionsmenüs ist gar nicht so einfach, aber ich beabsichtige, bald einen Blog-Artikel darüber zu veröffentlichen.
Hartnäckig
1

versuchen Sie diesen Code ....

 @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);
    }
Anoop
quelle
1
auf Android> 4.0 bekomme ichjava.lang.IllegalStateException: A factory has already been set on this LayoutInflater
zu Kra
1

Wenn Sie die Farbe für einen einzelnen Menüpunkt festlegen möchten, ist das Anpassen eines Symbolleistenmotivs nicht die richtige Lösung. Um dies zu erreichen, können Sie android: actionLayout und eine Aktionsansicht für den Menüpunkt verwenden.

Erstellen Sie zunächst eine XML-Layoutdatei für die Aktionsansicht. In diesem Beispiel verwenden wir eine Schaltfläche als Aktionsansicht:

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>

Im obigen Code-Snippet verwenden wir, um android:textColor="?android:attr/colorAccent"die Textfarbe der Schaltfläche anzupassen.

Fügen Sie dann in Ihre XML-Layoutdatei für das Menü app:actionLayout="@layout/menu_button"Folgendes ein:

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>

Zuletzt überschreiben Sie die onCreateOptionsMenu()Methode in Ihrer Aktivität:

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

... oder Fragment:

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

Weitere Informationen zu Aktionsansichten finden Sie im Android-Entwicklerhandbuch .

Alexander Poleschuk
quelle
0

So können Sie einen bestimmten Menüpunkt mit Farbe färben, funktioniert für alle API-Ebenen:

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

Auf diese Weise verlieren Sie den Hintergrundwahleffekt. Hier ist der Code zum Anwenden eines benutzerdefinierten Hintergrundwählers auf alle untergeordneten Menüelemente.

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

Hier ist auch die Hilfsfunktion:

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);
}
Box
quelle
0

Zum Ändern der Textfarbe können Sie einfach eine benutzerdefinierte Ansicht für das MenuItem festlegen und anschließend die Farbe für den Text definieren.

Beispielcode: MenuItem.setActionView ()

Freizeit
quelle
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Mischa