BottomNavigationView 中的背景颜色更改

Posted

技术标签:

【中文标题】BottomNavigationView 中的背景颜色更改【英文标题】:Background color change in BottomNavigationView 【发布时间】:2017-05-16 05:58:48 【问题描述】:

我已经实现了BottomNavigationView,它可以从新的支持库 25.0.0 中获得。这是我的代码

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

还有text.xmldrawable

<?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 时,它会显示错误 &lt;item&gt; tag requires a 'drawable' attribute or child tag defining a drawable

这是我尝试过的app:itemBackground

app:itemBackground="@drawable/text"

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

【问题讨论】:

创建一个可绘制文件并设置为app:itemBackground。根据BottomNavvigationView Doc可以只设置资源为背景。 尝试在你的项目中添加 android:drawable="@drawable/item_background_selected" @AnkitaShah 是的,这就是我所做的,我已经尝试过 app:itemBackground="@color/colorPrimary",这只是可绘制文件 @Charuka 完成了,我们不能将 android:color 用于itemBackground,我们必须在“”中使用android:drawable,您的答案部分正确。但是我们也不能不包括&lt;item&gt;android:color,这会产生错误。 @Ravi Rupareliya 很酷,我在用我的手机,否则我会拍得更好:P :)) 【参考方案1】:

从这个medium post找到答案

    我们需要使用android:state_checked 而不是android:state_enabledonNavigationItemSelected 中,您需要使用return true 而不是return false

并且要设置背景,我们不能在&lt;item&gt;中使用android:color,我们需要使用android:drawable

因此,当您为app:itemTextColorapp:itemIconTint 设置它时,它看起来如何 xml 文件

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

【讨论】:

如果您也可以在此处添加更新的视图 xml 以备将来使用,那就太好了 您实际上可以使用颜色资源而不是可绘制对象,但要使用android:drawable 属性,例如android:drawable="@color/colorPrimary"【参考方案2】:

我遇到了与 OP 类似的问题,但略有不同。如果你把 sth like@color/color_selector 放入 BottomNavigationView 的app:itemBackground="___"。这将导致视图隐藏在设计面板中,并且应用程序在启动时崩溃。虽然如果您将其设置为像@color/black 这样的恒定颜色,它就可以正常工作。

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

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

app:itemIconTintapp:itemTextColor 要求十六进制颜色,而 app:itemBackground 要求字面意义上的 Drawable。我们在colors.xml 中写入的&lt;color&gt; 元素是ColorDrawable。它源自 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,在这里它就像你设置一个常量颜色一样。

解决方案(和实践)是:

res/drawable/drawable_selector.xml 中使用(且仅)android:drawable。示例:

<?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 提供drawable。示例:

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

(值得注意的是,如果您使用的是 Android Studio,它的自动完成功能会告诉您哪些属性是合法且可用的,并且不建议您在 android:color 下的选择器中使用 android:colorres/drawable!)

【讨论】:

我不得不 onNavigationItemSelected 您需要使用 return true 而不是 return false 根据接受的答案,以便在遵循此方法时在项目单击时发生状态更改。 它说@drawable/drawable_selector 在构建时未找到,即使它确实为我自动完成了编辑:有史以来最奇怪的事情,它说“color/primary_bottom_select”缺失,即使我将它指向为@drawables 与@pete 相同的问题。有什么解决办法吗?【参考方案3】:

试试这是导航项选择监听器的示例代码。希望对你有帮助。

 @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_
android:layout_
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 选择器。

试试这个。

【讨论】:

我没有询问项目选择代码,我是在询问来自 xml 的 itemSelector。 顺便说一句,他已经找到了解决方案 :) 可能你正在添加一个额外的注释:P【参考方案4】:

首先创建 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"

【讨论】:

请在您的回答中添加一些解释 可以选择菜单项并使用波纹效果 Add 信息到您的答案。在 SO 代码答案质量低下。【参考方案5】:

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

<BottomNavigationView
...
android:theme="@style/CustomTheme"/>
<style name="CustomTheme">
   <item name="android:background">@color/colorPrimary</item>
</style>

【讨论】:

以上是关于BottomNavigationView 中的背景颜色更改的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Android BottomNavigationView 背景透明?

如何使BottomNavigationView项目背景透明

无法解析 BottomNavigationView 中的方法“setShiftingMode(Boolean)”

如何通过 Xamarin MvvmCross 中的 BottomNavigationView 在视图模型之间导航

BottomNavigationView 中的内容/图标未显示

如何使用 Kotlin 在 android 中的 BottomNavigationView 上设置 OnNavigationItemListener?