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


Answers:


3

通过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"
    ../>

以自定义样式:

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

对于itemIconTint和,itemTextColor您可以使用如下选择器:

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

对于,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>

就在最后要注意的。注意使用itemBackground
设置为@null使用通过设置NavigationView何时itemShapeAppearance和/或设置以编程方式生成的有形背景itemShapeAppearanceOverlay默认行为)。
使用itemShape*属性设置背景样式。
设置itemBackground将覆盖编程背景,并导致忽略itemShape *属性中设置的值。

在此处输入图片说明


131

itemBackgrounditemIconTint并且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>

注意:在这种情况下,文本颜色,图标色调和背景是静态的。如果要更改文本的颜色(例如,未选中则为粉红色,而选中则为蓝绿色),则应使用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>

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

同样的道理itemIconTintitemBackground需要一个资源ID。也请参阅文档


1
对于选中项目中的项目背景,只需使用<item name =“ colorControlHighlight”>#123456 </ item>
Xan

1
没错,但这也可能会改变其他视图的颜色,EditText至少在您在全局主题中定义它的时候。
reVerse

3
设置时有人遇到问题app:itemBackground="@drawable/my_ripple"吗?我碰到的是,当我按下一个项目时,最底部的那个反映的是涟漪效应,而不是我实际按下的那个。
哈维尔·门登萨(JavierMendonça),2015年

@JavierMendonca我也经历过同样的事情,但是我不知道该atm的修复程序-最有可能是一个bug,但也许值得针对这个特定问题提出一个单独的问题。
reVerse

3
请记住,要使其正常工作,您需要将其从android:state_checked更改为android:state_pressed。
Programista 2015年

96

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

图标和文字颜色

前两个选项(图标和文本)需要颜色状态列表资源- 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>
  • @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>

无需创建任何可模拟颜色的可绘制对象(在其他解决方案中,我看到了这样的建议-可能适用于较早的sdk版本),可以直接在此文件中使用颜色。在此示例文件中,我对未选中的项目和colorPrimary选中的项目使用透明颜色。

故障排除和重要说明

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

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

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

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


1
很好的答案,但我更喜欢为Navigationview创建一个主题。我需要覆盖哪个属性?
Xan

@MaciejSikora你救了我的命!我爱你们!嫁给我:)
Krzysiek '18

这是最重要的,否则无效。remember to set items as checkable。谢谢您提到这一点,没人能做到。
SimpleGuy

8

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


3
完美的答案,但是我需要在NavigationView主题中覆盖哪个属性才能控制背景,文本颜色和图标颜色?
Xan 2013年

是的,用创建样式,<item name="android:colorControlHighlight">@color/navigationDrawerTextNight</item>但是如何将样式应用于菜单项文本?itemTextColor不存在一种风格
某处某人

6

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

通话方式

setTextColorForMenuItem(item, R.color.colorPrimary);

如果您使用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);
        }

通话方式:

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

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

3

现在,在导航视图中,您还可以提供自己的项目视图。有了新的,appcompat-v7:23.1.0你可以

通过app:actionLayout或使用MenuItemCompat.setActionView()设置项目的自定义视图。

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

这样,您可以使用TextView创建自己的布局,并根据backgrounds/colors/fonts需要进行更改。希望这对您有所帮助:) 来源


0

如果要以编程方式执行此操作:

根据Jhon的回答:

您可以像这样使用Kotlin扩展名:

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

然后打电话

nav_view.setTextColorForMenuItems(Color.BLACK)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.