Изменение цвета фона в BottomNavigationView

Я реализовал BottomNavigationView который доступен из новой библиотеки поддержки 25.0.0. Вот мой код для этого

 <android.support.design.widget.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" app:itemBackground="@color/colorPrimary" app:itemIconTint="@drawable/text" app:itemTextColor="@drawable/text" app:menu="@menu/bottom_navigation_main" /> 

И text.xml drawable

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_enabled="true" /> <item android:color="@color/colorPrimaryDark" android:state_enabled="false" /> </selector> 

С помощью этого кода я могу изменить цвет текста при нажатии элемента меню, но когда я применяю то же самое к app:itemBackground он показывает, что <item> tag requires a 'drawable' attribute or child tag defining a drawable .

Это то, что я пробовал для app:itemBackground

 app:itemBackground="@drawable/text" 

Итак, мой вопрос в том, как изменить цвет фона выбранного пункта меню?

Solutions Collecting From Web of "Изменение цвета фона в BottomNavigationView"

Нашел ответ на эту среднюю должность

  1. Нам нужно использовать android:state_checked вместо android:state_enabled
  2. В onNavigationItemSelected вам нужно использовать return true вместо return false .

И для установки фона мы не можем использовать android:color в <item> , нам нужно использовать android:drawable

Итак, вот как выглядит файл xml, когда вы устанавливаете его для app:itemTextColor и app:itemIconTint

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

И установить app:itemBackground selector

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/banner_white" android:state_checked="true"/> <item android:drawable="@drawable/banner_green" android:state_checked="false"/> </selector> 

Здесь banner_white и banner_green – это png.

Я столкнулся с аналогичной проблемой с ОП, но немного по-другому. Если вы поместите sth как @color/color_selector в app:itemBackground="___" . Это заставит представление спрятаться в панели дизайна, а приложение будет раздавлено при запуске. Хотя он отлично работает, если вы просто установите его на постоянный цвет, например, @color/black .

Для более подробного объяснения я впился в ссылку android api. Теперь я думаю, что нашел ответ, который может разумно решить эту проблему. (Не может быть точным.)

Проблема в том, что вы предоставляете НЕ ТОЧНО, о чем они просили .

app:itemIconTint и app:itemTextColor запрашивает шестнадцатеричный цвет, а app:itemBackground запрашивает буквально Drawable . Элементы <color> которые мы пишем в colors.xml – это ColorDrawable . Он получен из Drawable, чтобы он мог кормить все три атрибута.

Однако, когда вы меняете его на использование селектора, все становится по-другому. Оба цвета шестнадцатеричного цвета и выталкиваемые имеют соответствующий селектор. Селектор действует как ресурс, который вы вставляете, но результат не является исходным. Это больше похоже на универсальную упаковку. Вы не можете передать шестнадцатеричный цвет атрибуту, которому требуется Drawable .

Селектор цвета на самом деле является ColorStateList , обеспечивает шестнадцатеричный цвет, находится в res/color . Вы можете использовать только атрибут android:color в этом файле. Это вызовет ошибку, если вы напишете android:drawable .
Выбираемый селектор – StateListDrawable , обеспечивает Drawable, находится в res/drawable . Вы должны написать android:drawable здесь можно android:drawable , но нет ошибки, если вы пишете android:color .

Однако android:color обеспечивает только шестнадцатеричный цвет, который нельзя распознать как Drawable , а app:itemBackground требует Drawable , поэтому приложение обречено. (Прямая причина)

Оба атрибута ( android:color and android:drawable ) принимают ColorDrawable , здесь он работает так же, как при установке постоянного цвета.

Решение (и практика):

  • Используйте (и только) android:drawable в res/drawable/drawable_selector.xml . Пример:

     <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/colorAccent" android:state_checked="true" /> <item android:drawable="@color/colorAccentDark" /> </selector> 
  • Используйте res/color/color_selector.xml когда ему нужен шестнадцатеричный цвет (во избежание путаницы). Пример:

     <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_checked="true"/> <item android:color="@color/colorPrimary" /> </selector> 
  • Предоставить app:itemBackground с возможностью app:itemBackground . Пример:

     <android.support.design.widget.BottomNavigationView ... app:itemBackground="@drawable/drawable_selector" app:itemIconTint="@color/color_selector" app:itemTextColor="@color/color_selector" ... /> 

(Стоит отметить, что если вы используете Android Studio, функция автозаполнения скажет вам, какие атрибуты являются законными и доступными, и это не означает, что вы android:color в селекторе под res/drawable !)

Попробуйте это, это пример кода элемента навигации, выбирающего слушателя. Надеюсь, что это поможет вам.

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

Альтернативное решение:

Выделите файл 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> 

Наконец добавьте приложение: 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.

Попробуй это.