更改导航抽屉中已检查菜单项的颜色

Gre*_*reg 93 android androiddesignsupport

我正在使用新的Android设计支持库在我的应用程序中实现导航抽屉.

我无法弄清楚如何更改所选项目的颜色!

这是菜单的xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
    <item
        android:id="@+id/navigation_item_1"
        android:icon="@drawable/ic_1"
        android:title="@string/navigation_item_1"/>

    <item
        android:id="@+id/navigation_item_2"
        android:icon="@drawable/ic_2"
        android:title="@string/navigation_item_2"/>
</group>
Run Code Online (Sandbox Code Playgroud)

这里是导航视图xml,它放在一个android.support.v4.widget.DrawerLayout:

<android.support.design.widget.NavigationView
    android:id="@+id/activity_main_navigationview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/black"
    app:itemTextColor="@color/primary_text"
    app:menu="@menu/menu_drawer">

    <TextView
        android:id="@+id/main_activity_version"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:textColor="@color/primary_text" />

</android.support.design.widget.NavigationView>
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助 !

[编辑]我已经看过这样的解决方案:更改android菜单的背景颜色.

这似乎是一个非常黑客,我认为通过新的设计支持库,会引入更清洁的东西?

Sas*_*_KP 233

那么你可以使用Color State Resource实现这一点.如果您注意到NavigationView您正在使用内部

app:itemIconTint="@color/black"
app:itemTextColor="@color/primary_text"
Run Code Online (Sandbox Code Playgroud)

在这里,而不是使用@color/black@color/primary_test,使用Color State List Resource.为此,首先xmlcolor目录内创建一个新的(例如drawer_item.xml)(应该在res目录中).如果您没有已命名的目录color,请创建一个.

现在里面drawer_item.xml做这样的事情

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="checked state color" android:state_checked="true" />
    <item android:color="your default color" />
</selector>
Run Code Online (Sandbox Code Playgroud)

最后一步是改变你的 NavigationView

<android.support.design.widget.NavigationView
    android:id="@+id/activity_main_navigationview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/drawer_item"  // notice here
    app:itemTextColor="@color/drawer_item" // and here
    app:itemBackground="@android:color/transparent"// and here for setting the background color to tranparent
    app:menu="@menu/menu_drawer">
Run Code Online (Sandbox Code Playgroud)

这样你可以使用不同的颜色状态列表资源IconTint,ItemTextColor,ItemBackground.

现在,当您将项目设置为已选中(以xml编程方式或以编程方式)时,特定项目将具有与未选中项目不同的颜色.

  • 对于ItemBackground,您需要使用drawable而不是color,因为您无法使用颜色资源定义背景. (31认同)

Ank*_*ush 61

我相信app:itemBackground期待一个可吸引人的.请按照以下步骤操作:

制作highlight_color.xml包含以下内容的可绘制文件:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
     <solid android:color="YOUR HIGHLIGHT COLOR"/>
</shape>
Run Code Online (Sandbox Code Playgroud)

nav_item_drawable.xml使用以下内容制作另一个可绘制文件:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/highlight_color" android:state_checked="true"/>
</selector>
Run Code Online (Sandbox Code Playgroud)

最后app:itemBackground在NavView中添加标记:

<android.support.design.widget.NavigationView
android:id="@+id/activity_main_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:itemIconTint="@color/black"
app:itemTextColor="@color/primary_text"
app:itemBackground="@drawable/nav_item_drawable"
app:menu="@menu/menu_drawer">
Run Code Online (Sandbox Code Playgroud)

这里的highlight_color.xml文件定义了背景的可绘制颜色.稍后,此颜色drawable将分配给nav_item_drawable.xml选择器.

这对我有用.希望这会有所帮助.

****************************************** 更新 **********************************************

虽然上面提到的答案可以很好地控制某些属性,但是我要描述的方式感觉更加SOLID并且有点冷却.

所以你可以做的是,你可以在NavigationView中定义一个ThemeOverlay,styles.xml如下所示:

    <style name="ThemeOverlay.AppCompat.navTheme">

        <!-- Color of text and icon when SELECTED -->
        <item name="colorPrimary">@color/color_of_your_choice</item> 

        <!-- Background color when SELECTED -->
        <item name="colorControlHighlight">@color/color_of_your_choice</item> 

    </style>
Run Code Online (Sandbox Code Playgroud)

现在将此ThemeOverlay应用于app:themeNavigationView的属性,如下所示:

<android.support.design.widget.NavigationView
android:id="@+id/activity_main_navigationview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:theme="@style/ThemeOverlay.AppCompat.navTheme"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/menu_drawer">
Run Code Online (Sandbox Code Playgroud)

我希望这将有所帮助.

  • **不要忘记在菜单 XML 中应用“CHECKABLE=TRUE”以使后台正常工作** (2认同)

Vik*_*tel 5

NavigateItem每当NavigateView单击项目时都需要设置为true

//listen for navigation events
NavigationView navigationView = (NavigationView)findViewById(R.id.navigation);
navigationView.setNavigationItemSelectedListener(this);
// select the correct nav menu item
navigationView.getMenu().findItem(mNavItemId).setChecked(true);
Run Code Online (Sandbox Code Playgroud)

添加NavigationItemSelectedListenerNavigationView

  @Override
  public boolean onNavigationItemSelected(final MenuItem menuItem) {
    // update highlighted item in the navigation menu
    menuItem.setChecked(true);
    mNavItemId = menuItem.getItemId();

    // allow some time after closing the drawer before performing real navigation
    // so the user can see what is happening
    mDrawerLayout.closeDrawer(GravityCompat.START);
    mDrawerActionHandler.postDelayed(new Runnable() {
      @Override
      public void run() {
        navigate(menuItem.getItemId());
      }
    }, DRAWER_CLOSE_DELAY_MS);
    return true;
  }
Run Code Online (Sandbox Code Playgroud)