简体   繁体   中英

Changing text color of menu item in navigation drawer

I'm trying to add a night theme for my app and I've wasted nearly three hours just trying to make the text and icons in my navigation drawer turn white along with the dark background. Here is the way I'm trying to go about doing this in onCreate() in MainActivity.java :

navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

    // This method will trigger onItemClick of navigation menu
    @Override
    public boolean onNavigationItemSelected(MenuItem menuItem) {

        // Checking if the item is in checked state or not, if not make it in checked state
        if (menuItem.isChecked())
            menuItem.setChecked(false);
        else menuItem.setChecked(true);

        if (nightMode == 0) {
            SpannableString spanString = new SpannableString(menuItem.getTitle().toString());
            spanString.setSpan(new ForegroundColorSpan(Color.WHITE), 0, spanString.length(), 0); // fix the color to white
            menuItem.setTitle(spanString);
        }

The nightMode boolean is irrelevant because it works. When night mode is set to on (0), whatever menu item is selected in the navigation drawer turns white. However, that only happens when each item is selected which is obviously inconvenient. Here is my drawer_dark.xml:

    <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group
        android:checkableBehavior="single">
        <item
            android:id="@+id/unitone"
            android:checked="true"
            android:icon="@drawable/one_white"
            android:title="Classical Period" />
        <item
            android:id="@+id/unittwo"
            android:checked="false"
            android:icon="@drawable/two_white"
            android:title="Postclassical Period" />
        <item
            android:id="@+id/unitthree"
            android:checked="false"
            android:icon="@drawable/three_white"
            android:title="Early Modern Era" />
        <item
            android:id="@+id/unitfour"
            android:checked="false"
            android:icon="@drawable/four_white"
            android:title="Dawn of Industrial Age" />
        <item
            android:id="@+id/unitfive"
            android:checked="false"
            android:icon="@drawable/five_white"
            android:title="Modern Era" />
    </group>
</menu>

I'm using white icons on a transparent background for each item, yet they show up as black on the black background of the navigation drawer. I've tried looking for an xml solution to changing the color of the text and I'm scratching my head because I don't know why this was overlooked.

Can someone offer me a dynamic solution in getting what I'm trying to achieve? All help is appreciated, thank you!

EDIT: I am not using a third party library, it's the NavigationView provided in the support library. Here's the XML layout:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:elevation="7dp"
    tools:context=".MainActivity"
    android:fitsSystemWindows="true" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/ColorDark" />

        <include layout="@layout/toolbar" />

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:background="#000"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/header"
        app:menu="@menu/drawer" />

</android.support.v4.widget.DrawerLayout>
 <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:background="#000"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/header"
        app:itemTextColor="your color"
        app:menu="@menu/drawer" />

Use app:itemIconTint in your NavigationView, ej:

<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/customColor"
    app:itemIconTint="@color/customColor"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_home"
    app:menu="@menu/activity_home_drawer" />

NavigationView has a method called setItemTextColor() . It uses a ColorStateList .

// FOR NAVIGATION VIEW ITEM TEXT COLOR
int[][] state = new int[][] {
        new int[] {-android.R.attr.state_enabled}, // disabled
        new int[] {android.R.attr.state_enabled}, // enabled
        new int[] {-android.R.attr.state_checked}, // unchecked
        new int[] { android.R.attr.state_pressed}  // pressed

};

int[] color = new int[] {
        Color.WHITE,
        Color.WHITE,
        Color.WHITE,
        Color.WHITE
};

ColorStateList csl = new ColorStateList(state, color);


// FOR NAVIGATION VIEW ITEM ICON COLOR
int[][] states = new int[][] {
        new int[] {-android.R.attr.state_enabled}, // disabled
        new int[] {android.R.attr.state_enabled}, // enabled
        new int[] {-android.R.attr.state_checked}, // unchecked
        new int[] { android.R.attr.state_pressed}  // pressed

};

int[] colors = new int[] {
        Color.WHITE,
        Color.WHITE,
        Color.WHITE,
        Color.WHITE
};

ColorStateList csl2 = new ColorStateList(states, colors);

Here is where I got that answer. And then right after assigning my NavigationView:

if (nightMode == 0) {
            navigationView.setItemTextColor(csl);
            navigationView.setItemIconTintList(csl2);
        }

More options:

you can also change the group title by overriding "textColorSecondary"

In your styles.xml

<style name="AppTheme.NavigationView">
    <item name="android:textColorSecondary">#FFFFFF</item>
</style>

In your layout

<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:menu="@menu/activity_main_menu_drawer_drawer"
    android:theme="@style/AppTheme.NavigationView"
    app:itemIconTint="@color/colorPrimary"
    app:itemTextColor="@color/white"/>

add app:itemTextColor="#fff" in your NavigationView like

 <android.support.design.widget.NavigationView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    app:menu="@menu/slider_menu"
    android:background="@color/colorAccent"
    app:itemTextColor="#fff"
    android:id="@+id/navigation_view"
    android:layout_gravity="start"/>

I used below code to change Navigation drawer text color in my app.

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setItemTextColor(ColorStateList.valueOf(Color.WHITE));

You can use drawables in

app:itemTextColor app:itemIconTint

then you can control the checked state and normal state using a drawable

<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:itemHorizontalPadding="@dimen/margin_30"
            app:itemIconTint="@drawable/drawer_item_color"
            app:itemTextColor="@drawable/drawer_item_color"
            android:theme="@style/NavigationView"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/drawer_menu">

drawer_item_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/selectedColor" android:state_checked="true" />
    <item android:color="@color/normalColor" />
</selector>

In Future if anyone comes here using, Navigation Drawer Activity (provided by Studio in Activity Prompt window)

The answer is -

Use this before OnCreate() in MainActivity

int[][] state = new int[][] {
        new int[] {android.R.attr.state_checked}, // checked
        new int[] {-android.R.attr.state_checked}
};

int[] color = new int[] {
        Color.rgb(255,46,84),
        (Color.BLACK)
};

ColorStateList csl = new ColorStateList(state, color);

int[][] state2 = new int[][] {
        new int[] {android.R.attr.state_checked}, // checked
        new int[] {-android.R.attr.state_checked}
};

int[] color2 = new int[] {
        Color.rgb(255,46,84),
        (Color.GRAY)
};

ColorStateList csl2 = new ColorStateList(state2, color2);

and use this in onNavigationItemSelected() in MainActivity (you dont need to Write this function if you use Navigation Drawer activity, it will be added in MainActivity).

 NavigationView nav = (NavigationView) findViewById(R.id.nav_view);
    nav.setItemTextColor(csl);
    nav.setItemIconTintList(csl2);
    nav.setItemBackgroundResource(R.color.white);

Tip - add this code before If else Condition in onNavigationItemSelected()

This works for me. in place of customTheme you can put you theme in styles. in this code you can also change the font and text size.

    <style name="MyTheme.NavMenu" parent="CustomTheme">
            <item name="android:textSize">16sp</item>
            <item name="android:fontFamily">@font/ssp_semi_bold</item>
            <item name="android:textColorPrimary">@color/yourcolor</item>
        </style>

here is my navigation view

<android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:theme="@style/MyTheme.NavMenu"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer">

        <include layout="@layout/layout_update_available"/>

    </android.support.design.widget.NavigationView>

You can do simply by adding your theme to your navigation View.

    <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"
    android:background="@color/colorPrimary"
    android:theme="@style/AppTheme.NavigationView"
    app:headerLayout="@layout/nav_header_drawer"
    app:menu="@menu/activity_drawer_drawer"/>

and in your style.xml file, you will add this theme

   <style name="AppTheme.NavigationView" >
    <item name="colorPrimary">@color/text_color_changed_onClick</item>
    <item name="android:textColorPrimary">@color/Your_default_text_color</item>
</style>

try this in java class

yourNavigationView.setItemTextColor(new ColorStateList(
            new int [] [] {
                    new int [] {android.R.attr.state_pressed},
                    new int [] {android.R.attr.state_focused},
                    new int [] {}
            },
            new int [] {
                    Color.rgb (255, 128, 192),
                    Color.rgb (100, 200, 192),
                    Color.WHITE
            }
    ));

This may help It worked for me

Go to activity_"navigation activity name".xml Inside NavigationView insert this code

app:itemTextColor="color of your choice"

In my case, I needed to change the color of just one menu item - "Logout". I had to run a recursion and changed the title color:

NavigationView nvDrawer;
Menu menu = nvDrawer.getMenu();
    for (int i = 0; i < menu.size(); i ++){
        MenuItem menuItem = menu.getItem(i);

        if (menuItem.getTitle().equals("Logout")){

            SpannableString spanString = new SpannableString(menuItem.getTitle().toString());
            spanString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.red)), 0, spanString.length(), 0);
            menuItem.setTitle(spanString);

        }

    }

I did this in the Activity's onCreate method.

You can also define a custom theme that is derived from your base theme:

<android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:id="@+id/nav_view"
        app:headerLayout="@layout/nav_view_header"
        app:menu="@layout/nav_view_menu"
        app:theme="@style/MyTheme.NavMenu" />

and then in your styles.xml file:

  <style name="MyTheme.NavMenu" parent="MyTheme.Base">
    <item name="android:textColorPrimary">@color/yourcolor</item>
  </style>

you can also apply more attributes to the custom theme.

To change the individual text color of a single item, use a SpannableString like below:

NavigationView navDrawer;
Menu menu = navDrawer.getMenu();

SpannableString spannableString = new SpannableString("Menu item"));
        spannableString.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorPrimary)), 0, spannableString.length(), 0);

menu.findItem(R.id.nav_item).setTitle(spannableString);
 <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/drawer_item_bg"
        app:headerLayout="@layout/nav_header_home"
        app:menu="@menu/app_home_drawer" />

To set Item Background using app:itemBackground

drawer_item_bg.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <item android:top="-2dp" android:right="-2dp" android:left="-2dp">
        <shape>
            <padding android:bottom="0dp" android:left="15dp" android:right="0dp" android:top="0dp"/>
            <solid android:color="@android:color/transparent" />
            <stroke
                android:width="0.5dp"
                android:color="#CACACA" />
        </shape>
    </item>
</layer-list>

itemIconTint, if u want to change icon color

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:itemTextColor="@color/colorPrimary"
            app:itemIconTint="@color/colorPrimary"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer" />

to change text color of Navigation Drawer

we use app:itemTextColor="@color/white"

to change incon color of navigation Drawer

use app:itemIconTint="@color/black"


    <com.google.android.material.navigation.NavigationView
        android:id="@+id/naView"
        app:itemIconTint="@color/black"
        android:layout_width="match_parent"
        app:menu="@menu/navmenu"
        app:itemTextColor="@color/white"
        app:headerLayout="@layout/nav_header"
        android:layout_height="match_parent"
        app:itemTextAppearance="?android:textAppearanceMedium"
        android:fitsSystemWindows="true"
        android:layout_gravity="start"
        />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM