BottomNavigationView 中的背景颜色更改
Background color change in 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
可绘制
<?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"
所以我的问题是如何更改所选菜单项的背景颜色?
从这个 medium post
中找到了答案
- 我们需要使用
android:state_checked
而不是 android:state_enabled
- 在
onNavigationItemSelected
中,您需要使用 return true
而不是 return false
。
和设置背景,我们不能在<item>
中使用android:color
,我们需要使用android:drawable
所以当你为 app:itemTextColor
和 app: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_white
和 banner_green
是 png。
试试这个,它是导航项 select 侦听器的示例代码。希望对你有帮助。
@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 文件为背景定义了纯色可绘制对象。后来这个颜色drawable被分配给nav_item_drawable.xml selector.
试试这个。
我遇到了与 OP 类似的问题,但有些不同。如果您将 @color/color_selector
之类的东西放入 BottomNavigationView 的 app:itemBackground="___"
。它会导致视图隐藏在设计面板中,并且应用程序在启动时崩溃。虽然如果你只是将它设置为像 @color/black
.
这样的恒定颜色,它就可以正常工作
为了更深入的解释,我深入研究了 android api 参考资料。现在我想我找到了可以合理解决这个问题的答案。 (可能不准确。)
问题是,您提供的与他们要求的不完全相同。
app:itemIconTint
和 app:itemTextColor
要求十六进制颜色,而 app:itemBackground
要求字面上的 Drawable. The <color>
elements we write in colors.xml
are ColorDrawable。它派生自 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:color
和 android: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
可绘制对象。示例:
<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
!)
首先创建 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"
一个简单的方法对我有用:
<BottomNavigationView
...
android:theme="@style/CustomTheme"/>
<style name="CustomTheme">
<item name="android:background">@color/colorPrimary</item>
</style>
我已经实现了 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"
所以我的问题是如何更改所选菜单项的背景颜色?
从这个 medium post
中找到了答案- 我们需要使用
android:state_checked
而不是android:state_enabled
- 在
onNavigationItemSelected
中,您需要使用return true
而不是return false
。
和设置背景,我们不能在<item>
中使用android:color
,我们需要使用android:drawable
所以当你为 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
选择器
<?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。
试试这个,它是导航项 select 侦听器的示例代码。希望对你有帮助。
@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 文件为背景定义了纯色可绘制对象。后来这个颜色drawable被分配给nav_item_drawable.xml selector.
试试这个。
我遇到了与 OP 类似的问题,但有些不同。如果您将 @color/color_selector
之类的东西放入 BottomNavigationView 的 app:itemBackground="___"
。它会导致视图隐藏在设计面板中,并且应用程序在启动时崩溃。虽然如果你只是将它设置为像 @color/black
.
为了更深入的解释,我深入研究了 android api 参考资料。现在我想我找到了可以合理解决这个问题的答案。 (可能不准确。)
问题是,您提供的与他们要求的不完全相同。
app:itemIconTint
和 app:itemTextColor
要求十六进制颜色,而 app:itemBackground
要求字面上的 Drawable. The <color>
elements we write in colors.xml
are ColorDrawable。它派生自 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:color
和 android: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
可绘制对象。示例:<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
!)
首先创建 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"
一个简单的方法对我有用:
<BottomNavigationView
...
android:theme="@style/CustomTheme"/>
<style name="CustomTheme">
<item name="android:background">@color/colorPrimary</item>
</style>