如何在NavigationView中自定义项目背景和项目文本颜色?

Xan*_*Xan 73 android drawerlayout material-design android-design-library navigationview

我想实现Material Design Docs中显示的类似内容.

colorControlHighlight 用于检查项目的背景.

我需要自定义:

  • 背景未经检查
  • 文字颜色检查
  • 文本颜色未选中

reV*_*rse 127

itemBackground,itemIconTint并且itemTextColor是可以设置的简单xml属性,但您必须使用自定义前缀而不是android:一个.

<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>
Run Code Online (Sandbox Code Playgroud)

注意:在这种情况下,文本颜色,图标色调和背景是静态的.如果你想改变文本的颜色(例如,未经检查时为粉红色,选中时为蓝绿色),则应使用a ColorStateList.

创建一个新的*.xml文件/res/color- 让我们将其命名为state_list.xml - 包含以下内容:

<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>
Run Code Online (Sandbox Code Playgroud)

然后简单地像这样引用它: app:itemTextColor="@color/state_list"

同样的道理itemIconTint.itemBackground期望资源ID.也请参阅文档.

  • 任何人在设置`app:itemBackground ="@ drawable/my_ripple"时遇到问题?碰巧我,当我按下一个项目时,最底部的那个反映了涟漪效应而不是我实际按下的那个. (3认同)
  • 请记住,对于按下工作,你需要将它从android:state_checked更改为android:state_pressed. (3认同)

Mac*_*ora 89

NavigationDrawer(NavigationView)有三个选项用于配置已检查/选定的项目.

app:itemIconTint="@color/menu_text_color" //icon color
app:itemTextColor="@color/menu_text_color" //text color
app:itemBackground="@drawable/menu_background_color" //background
Run Code Online (Sandbox Code Playgroud)

图标和文字颜色

前两个选项(图标和文本)需要颜色状态列表资源 - https://developer.android.com/guide/topics/resources/color-list-resource.html.

menu_text_color需要以res/color创建此类资源.此文件内容应类似于:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)
  • @color/colorWhite - 用于已检查项目的颜色资源

  • @color/colorBlack - 用于未选中项目的颜色资源

我为两者创建了一个资源,但是可以创建两个独立的文件 - 一个用于文本,一个用于图标.

背景(itemBackground)

后台选项需要可绘制资源而不是颜色,每次尝试设置颜色都将以异常结束.需要在res/drawable中创建可绘制资源,其内容应类似于:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

没有必要创建任何模拟颜色的drawable(在其他解决方案中我看到了这样的命题 - 可能是较旧的sdk版本),颜色可以直接在这个文件中使用.在这个示例文件中,我使用透明颜色作为未选中项目和colorPrimary已选中项目.

故障排除和重要说明

  • 在后台资源中,始终使用state_checked ="false"而不是默认值,默认颜色不起作用
  • 对于动态/编程创建的菜单,请记住将项目设置为可检查:

代码示例(动态菜单项添加):

  menu.add(group_id, item_id, Menu.NONE, item_name).setCheckable(true).setChecked(false);
Run Code Online (Sandbox Code Playgroud)

如果项目不会设置为可检查,则背景将不起作用(文本和图标颜色令人惊讶将按预期工作).


Mim*_*oli 8

使用colorControlHighlight对我来说是一个很好的解决方案.请注意,使用最新的支持库,您可以为每个小部件定义主题(不仅仅是样式); 例如,您可以将colorControlHighlight定义为NavigationView主题,这不会应用于其他小部件.

  • 完美的答案,但我需要在NavigationView主题中覆盖哪些attr来控制background,textcolor和iconcolor? (3认同)

Gab*_*tti 6

通过MaterialComponents 库,您可以使用这些属性:

  • app:itemShapeFillColor: 背景项目颜色
  • app:itemIconTint: 图标色调
  • app:itemTextColor: 文字颜色

在布局中:

<com.google.android.material.navigation.NavigationView
    app:itemShapeFillColor="@color/shape_selector"
    app:itemIconTint="@color/icon_tint_selector"
    app:itemTextColor="@color/text_color_selector"
    ../>
Run Code Online (Sandbox Code Playgroud)

在自定义样式中:

<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>
Run Code Online (Sandbox Code Playgroud)

对于itemIconTintanditemTextColor你可以使用这样的选择器:

<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>
Run Code Online (Sandbox Code Playgroud)

对于itemShapeFillColor您可以使用如下选择器:

<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>
Run Code Online (Sandbox Code Playgroud)

只是最后一点。注意使用到itemBackground.
它被设置为@null使用由NavigationView何时itemShapeAppearance和/或被itemShapeAppearanceOverlay设置(默认行为)以编程方式生成的形状背景。
此背景使用itemShape*属性进行样式设置。
设置itemBackground将覆盖编程背景并导致在 itemShape* 属性中设置的值被忽略。

在此处输入图片说明


Ahm*_*deh 5

您可以以编程方式使用此代码:

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);
Run Code Online (Sandbox Code Playgroud)


Jho*_*hon 5

如果您只想更改基于事件的活动中的一个菜单项颜色,请参阅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);
}
Run Code Online (Sandbox Code Playgroud)

调用方法

setTextColorForMenuItem(item, R.color.colorPrimary);
Run Code Online (Sandbox Code Playgroud)

如果您使用Xamarin Android,请尝试以下操作:

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);
        }
Run Code Online (Sandbox Code Playgroud)

呼叫方法:

SetTextColorForMenuItem(navigationView.Menu.GetItem(0), Android.Graphics.Color.OrangeRed);
Run Code Online (Sandbox Code Playgroud)