Изменение цвета выбранного элемента меню в навигационном ящике

Я использую новую библиотеку поддержки Android Design для реализации ящика навигации в своем приложении.

Я не могу понять, как изменить цвет выбранного элемента!

Вот 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> 

И вот XML-интерфейс navigationview, который находится внутри 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> 

Спасибо за помощь !

[EDIT] Я уже рассмотрел такие решения, как этот: Изменить цвет фона в меню Android .

Кажется, это довольно хак, и я подумал, что с новой библиотекой поддержки дизайна было бы введено что-то более чистое?

Solutions Collecting From Web of "Изменение цвета выбранного элемента меню в навигационном ящике"

Ну, вы можете достичь этого, используя Color State Resource . Если вы заметили внутри своего NavigationView экрана, вы используете

 app:itemIconTint="@color/black" app:itemTextColor="@color/primary_text" 

Здесь вместо использования @color/black или @color/primary_test используйте Color State List Resource состояний Color State List Resource . Для этого сначала создайте новый xml (например, drawer_item.xml) внутри каталога color (который должен находиться внутри каталога 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> 

Заключительным шагом было бы изменить ваше 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"> 

Подобно этому вы можете использовать отдельные ресурсы списка состояний цвета для IconTint , ItemTextColor , ItemBackground .

Теперь, когда вы устанавливаете элемент как отмеченный (либо в xml либо программно), конкретный элемент будет иметь другой цвет, чем непроверенные.

Я считаю, 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> 

Создайте еще один файл для 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> 

Наконец добавьте 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"> 

Здесь файл highlight_color.xml определяет сплошной цвет для фона. Позже этот цвет можно присвоить селектору nav_item_drawable.xml.

Это сработало для меня. Надеюсь, это поможет.

********************************************** ОБНОВЛЕНО *** *******************************************

Хотя вышеупомянутый ответ дает вам прекрасный контроль над некоторыми свойствами, но способ, которым я собираюсь описать, чувствует себя более ТВЕРДОЙ и немного ОХЛАЖДЕН .

Итак, что вы можете сделать, вы можете определить ThemeOverlay в styles.xml для NavigationView следующим образом:

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

Теперь примените этот ThemeOverlay к атрибуту app:theme для 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:theme="@style/ThemeOverlay.AppCompat.navTheme" app:headerLayout="@layout/drawer_header" app:menu="@menu/menu_drawer"> 

Я надеюсь, это поможет.

Нужно установить, что NavigateItem проверяется true, когда элемент в NavigateView нажат

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

Добавить NavigationItemSelectedListener в NavigationView

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

Вот еще один способ добиться этого:

 public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { item.setEnabled(true); item.setTitle(Html.fromHtml("<font color='#ff3824'>Settings</font>")); return false; } }); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } 

}