36

我已经实现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可绘制

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

所以我的问题是如何更改所选菜单项的背景颜色?

4

5 回答 5

44

从这个媒体帖子中找到了答案

  1. 我们需要使用android:state_checked而不是android:state_enabled
  2. onNavigationItemSelected你需要使用return true而不是return false.

并且要设置背景,我们不能使用android:colorin <item>,我们需要使用android:drawable

因此,当您设置它时,它看起来如何 xmlapp: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选择器

<?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_whitebanner_green是png。

于 2017-01-02T05:49:30.227 回答
21

我遇到了与 OP 类似的问题,但略有不同。如果你把 sth like@color/color_selector放到 BottomNavigationView 的app:itemBackground="___". 这将导致视图隐藏在设计面板中,并且应用程序在启动时崩溃。尽管如果您将其设置为恒定颜色(例如@color/black.

为了更深入的解释,我深入研究了 android api 参考。现在我想我已经找到了可以合理解决这个问题的答案。(可能不准确。)

问题是,您提供的并不完全符合他们的要求

app:itemIconTintapp:itemTextColor要求十六进制颜色,同时app:itemBackground要求字面上的Drawable<color>我们写入的元素colors.xmlColorDrawable。它是从Drawable派生的,因此它可以提供所有三个属性。

但是,当您将其更改为使用选择器时,情况会有所不同。hex color 和 drawable 都有一个对应的选择器。选择器的作用类似于您放入的资源,但结果不是原始的。它更像是一个单一用途的包装器。您不能将十六进制颜色提供给需要Drawable的属性。

颜色选择器实际上是一个ColorStateList,提供十六进制颜色,位于res/color. 您只能使用android:color此文件中的属性。写的话会提示错误android:drawable
drawable 选择器是StateListDrawable,提供 Drawable ,位于res/drawable. 你应该android:drawable在这里写,但如果你写,没有错误android:color

但是android:color只提供了一个无法识别为Drawable的十六进制颜色,而app:itemBackground需要一个Drawable,因此该应用程序注定要失败。(直接原因)

两个属性 (android:colorandroid:drawable) 都接受一个ColorDrawable,在这里它就像你设置一个常量颜色一样工作。

解决方案(和实践)是:

  • android:drawable在 a 中使用(且仅)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:itemBackgrounddrawable。例子:

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

于 2017-05-29T13:01:10.927 回答
2

试试这个,它是导航项选择侦听器的示例代码。希望它可以帮助你。

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

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

<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 选择器。

试试这个。

于 2017-01-02T06:00:38.900 回答
2

首先创建 xml bottom_navigation_items 与

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <selector>
            <item
                android:drawable="@color/primary_bottom_select"
                android:state_checked="true" />
            <item
                android:drawable="@color/bottom_navigation"
                android:state_checked="false" />
        </selector>
    </item>
</ripple>

第二:添加app:itemBackground="@drawable/bottom_navigation_items"

于 2019-03-24T23:11:40.170 回答
1

一个简单的方法对我有用:

<BottomNavigationView
...
android:theme="@style/CustomTheme"/>
<style name="CustomTheme">
   <item name="android:background">@color/colorPrimary</item>
</style>
于 2020-11-09T07:58:59.490 回答