Wie kann ich den Hintergrund des Elements und die Farbe des Elementtextes in NavigationView anpassen?

Antworten:

3

Mit der MaterialComponents Library können Sie folgende Attribute verwenden:

  • app:itemShapeFillColor: Hintergrundfarbe
  • app:itemIconTint: Symboltönung
  • app:itemTextColor: Textfarbe

Im Layout:

<com.google.android.material.navigation.NavigationView
    app:itemShapeFillColor="@color/shape_selector"
    app:itemIconTint="@color/icon_tint_selector"
    app:itemTextColor="@color/text_color_selector"
    ../>

In einem benutzerdefinierten Stil:

<style name="..." parent="Widget.MaterialComponents.NavigationView" >
   <item name="itemShapeFillColor">@color/shape_selector</item>
   <item name="itemIconTint">@color/icon_tint_selector</item>
   <item name="itemTextColor">@color/text_color_selector</item>
</style>

Für das itemIconTintund können itemTextColorSie einen Selektor wie folgt verwenden:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorPrimary" android:state_checked="true"/>
  <item android:alpha="0.38" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
  <item android:color="?attr/colorOnSurface"/>
</selector>

Für die können itemShapeFillColorSie einen Selektor verwenden wie:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_activated="true"/>
  <item android:alpha="0.12" android:color="?attr/colorPrimary" android:state_checked="true"/>
  <item android:color="@android:color/transparent"/>
</selector>

Nur eine letzte Anmerkung . Achten Sie auf die Verwendung der itemBackground.
Es ist so eingestellt, @nulldass ein geformter Hintergrund verwendet wird, der programmgesteuert generiert wird, NavigationViewwenn itemShapeAppearanceund / oder festgelegt itemShapeAppearanceOverlayist ( Standardverhalten ).
Dieser Hintergrund wird anhand der itemShape*Attribute gestaltet.
Durch die Einstellung itemBackgroundwird der programmatische Hintergrund überschrieben und die in den itemShape * -Attributen festgelegten Werte werden ignoriert.

Geben Sie hier die Bildbeschreibung ein

Gabriele Mariotti
quelle
131

itemBackground, itemIconTintUnd itemTextColorsind einfache XML-Attribute , die eingestellt werden können, wenn Sie anstelle des einen benutzerdefinierten Präfix verwenden müssen android:ein.

Beispiel

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- Other layout views -->

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:itemBackground="@drawable/my_ripple"
        app:itemIconTint="#2196f3"
        app:itemTextColor="#009688"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer_view" />

</android.support.v4.widget.DrawerLayout>

Hinweis: In diesem Fall sind Textfarbe, Symboltönung und Hintergrund statisch. Wenn Sie die Farbe des Textes ändern möchten (z. B. rosa, wenn nicht markiert, und blaugrün, wenn aktiviert), sollten Sie a verwenden ColorStateList.

Beispiel

Erstellen Sie eine neue * .xml-Datei in /res/color- nennen wir sie state_list.xml - mit folgendem Inhalt:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- This is used when the Navigation Item is checked -->
    <item android:color="#009688" android:state_checked="true" />
    <!-- This is the default text color -->
    <item android:color="#E91E63" />
</selector>

und dann einfach so referenzieren: app:itemTextColor="@color/state_list"

Das gilt auch für itemIconTint. itemBackgrounderwartet eine Ressourcen-ID. Siehe auch die Dokumente .

umkehren
quelle
1
Verwenden Sie für den Artikelhintergrund im aktivierten Artikel einfach <item name = "colorControlHighlight"> # 123456 </ item>
Xan
1
Das stimmt, aber dies könnte auch die Farbe anderer Ansichten ändern, EditTextzumindest wenn Sie sie in Ihrem globalen Thema definieren.
reVerse
3
Hat jemand Probleme beim Einstellen app:itemBackground="@drawable/my_ripple"? Es passiert mir, dass wenn ich einen Gegenstand drücke, der ganz unten den Welleneffekt widerspiegelt, anstatt den, den ich tatsächlich drücke.
Javier Mendonça
@JavierMendonca Ich habe das gleiche erlebt, aber ich kenne keine Lösung für diesen Geldautomaten - höchstwahrscheinlich ist dies ein Fehler, aber vielleicht lohnt es sich, eine separate Frage für dieses spezielle Problem zu stellen.
ReVerse
3
Denken Sie daran, dass Sie zum Drücken von "drücken" den Befehl "android: state_checked" in "android: state_pressed" ändern müssen.
Programista
96

NavigationDrawer (NavigationView) bietet drei Optionen für die Konfiguration von markierten / ausgewählten Elementen.

app:itemIconTint="@color/menu_text_color" //icon color
app:itemTextColor="@color/menu_text_color" //text color
app:itemBackground="@drawable/menu_background_color" //background

Symbol- und Textfarbe

Die ersten beiden Optionen (Symbol und Text) benötigen eine Ressource für die Farbstatusliste - https://developer.android.com/guide/topics/resources/color-list-resource.html .

Diese menu_text_colorRessource muss in res / color erstellt werden . Dieser Dateiinhalt sollte ungefähr so ​​aussehen:

<!-- res/color/menu_text_color.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="@color/colorWhite" android:state_checked="true" />
  <item android:color="@color/colorBlack" android:state_checked="false"/>
</selector>
  • @color/colorWhite - Farbressource für markiertes Element

  • @color/colorBlack - Farbressource für ungeprüftes Element

Ich habe eine Ressource für beide erstellt, aber es ist möglich, zwei getrennte Dateien zu erstellen - eine für Text und eine für das Symbol.

Hintergrund (itemBackground)

Die Hintergrundoption benötigt eine zeichnbare Ressource anstelle einer Farbe. Jeder Versuch, die Farbe festzulegen, endet ausnahmsweise. Zeichnungsfähige Ressourcen müssen in res / drawable erstellt werden und ihr Inhalt sollte folgendermaßen aussehen:

<!-- res/drawable/menu_background_color.xml -->
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@android:color/transparent"  android:state_checked="false"/>
  <item android:drawable="@color/colorPrimary" android:state_checked="true"/>
</selector>

Es ist nicht erforderlich, Zeichen zu erstellen, die Farbe simulieren (in anderen Lösungen habe ich solche Vorschläge gesehen - möglicherweise für ältere SDK-Versionen). Farbe kann direkt in dieser Datei verwendet werden. In dieser Beispieldatei verwende ich eine transparente Farbe für nicht geprüftes Element und colorPrimaryfür geprüftes Element.

Fehlerbehebung und wichtige Hinweise

  • Verwenden Sie in der Hintergrundressource immer state_checked = "false" anstelle von default. Mit der Standardfarbe funktioniert dies nicht
  • Denken Sie bei dynamisch / programmgesteuert erstellten Menüs daran, Elemente als überprüfbar festzulegen :

Codebeispiel (dynamischer Menüpunkt hinzufügen):

  menu.add(group_id, item_id, Menu.NONE, item_name).setCheckable(true).setChecked(false);

Wenn Elemente nicht als überprüfbar festgelegt werden, funktioniert der Hintergrund nicht (überraschende Text- und Symbolfarben funktionieren wie erwartet).

Maciej Sikora
quelle
1
Gute Antwort, aber ich ziehe es vor, ein Thema für die Navigationsansicht zu erstellen. Welchen attr muss ich überschreiben?
Xan
@ MaciejSikora Du rettest mein Leben! Ich liebe euch Männer! Heirate mich :)
Krzysiek
Dies ist das Wichtigste, sonst funktioniert nichts. remember to set items as checkable. Vielen Dank, dass Sie dies erwähnt haben, was niemand getan hat.
SimpleGuy
8

Die Verwendung von colorControlHighlight ist für mich eine gute Lösung. Beachten Sie, dass Sie mit der neuesten Support-Bibliothek für jedes Widget ein Thema (nicht nur den Stil) definieren können. Sie können beispielsweise colorControlHighlight im NavigationView-Design definieren. Dies wird nicht auf die übrigen Widgets angewendet.

Mimmo Grottoli
quelle
3
perfekte Antwort, aber welchen attr muss ich im NavigationView-Design überschreiben, um Hintergrund, Textfarbe und Symbolfarbe zu steuern?
Xan
Ja sicher, erstellen Sie einen Stil mit, <item name="android:colorControlHighlight">@color/navigationDrawerTextNight</item>aber wie wird er auf den Menüelementtext angewendet? itemTextColorexistiert nicht in einem Stil
Jemand irgendwo
6

Wenn Sie nur eine Menüelementfarbe aus Ihrer Aktivität basierend auf Ereignissen ändern möchten, lesen Sie diesen Blog von HANIHASHEMI:

https://hanihashemi.com/2017/05/06/change-text-color-of-menuitem-in-navigation-drawer/

private void setTextColorForMenuItem(MenuItem menuItem, @ColorRes int color) {
  SpannableString spanString = new SpannableString(menuItem.getTitle().toString());
  spanString.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, color)), 0, spanString.length(), 0);
  menuItem.setTitle(spanString);
}

Methode aufrufen

setTextColorForMenuItem(item, R.color.colorPrimary);

Wenn Sie mit Xamarin Android arbeiten, versuchen Sie Folgendes:

private void SetTextColorForMenuItem(IMenuItem menuItem, Android.Graphics.Color color)
        {
            SpannableString spanString = new SpannableString(menuItem.TitleFormatted.ToString());
            spanString.SetSpan(new ForegroundColorSpan(color), 0, spanString.Length(), 0);
            menuItem.SetTitle(spanString);
        }

Aufrufmethode:

SetTextColorForMenuItem(navigationView.Menu.GetItem(0), Android.Graphics.Color.OrangeRed);
Jhon
quelle
5

Sie können diesen Code programmgesteuert verwenden:

int[][] states = new int[][] {
    new int[] { android.R.attr.state_enabled}, // enabled
    new int[] {-android.R.attr.state_enabled}, // disabled
    new int[] {-android.R.attr.state_checked}, // unchecked
    new int[] { android.R.attr.state_pressed}  // pressed
};

int[] colors = new int[] {
    Color.BLACK,
    Color.RED,
    Color.GREEN,
    Color.BLUE
};

ColorStateList myList = new ColorStateList(states, colors);

  nav_view.setItemIconTintList(myList);
Ahmad Aghazadeh
quelle
3

In der Navigationsansicht können Sie jetzt auch Ihre eigene Elementansicht bereitstellen. Mit neu appcompat-v7:23.1.0kannst du

Festlegen benutzerdefinierter Ansichten für Elemente über die App: actionLayout oder mithilfe von MenuItemCompat.setActionView ().

View view = View.inflate(context, R.layout.your_custom_nav_layout_item, null);
MenuItemCompat.setActionView(menuItem, view); 

Auf diese Weise können Sie mit TextView Ihr eigenes Layout erstellen und nach Belieben ändern backgrounds/colors/fonts. Hoffe das war hilfreich :) Quelle

hkop
quelle
0

Wenn Sie dies programmgesteuert tun möchten:

Basierend auf Jhons Antwort:

Sie können die Kotlin-Erweiterung folgendermaßen verwenden:

fun NavigationView.setTextColorForMenuItems(@ColorInt color: Int) {
    for (i: Int in 0 until menu.size()) {
        val menuItem = menu.getItem(i)
        val spanString = SpannableString(menuItem.title.toString())
        spanString.setSpan(ForegroundColorSpan(color), 0, spanString.length, 0)
        menuItem.title = spanString
    }
}

Dann ruf an

nav_view.setTextColorForMenuItems(Color.BLACK)
Alex Smith
quelle
-1

Sie können dies mit der folgenden Anweisung tun:

navigationView.setItemBackground(ContextCompat.getDrawable(CustomerHomeActivity.this, R.color.transparent));
Sohaib Khalid
quelle