Android - 更改底部导航栏每个选项卡的图标和标题颜色

4

我正在尝试制作一个有点棘手的底部导航。
实际上,我想要这种底部导航:
bottom_nav_1 bottom_nav_2
当选择每个选项卡时,它们都有不同的颜色。例如,在选择“measure”时将以红色显示(图标和标题),而在选择“profile”时将为绿色...
因此,我尝试使用每个菜单项的选择器
但是颜色没有应用。图标成功更改(我尝试在选择项目时放置完全不同的图标),但是选项卡标题的颜色没有更改。
我尝试删除底部导航中的两个属性:

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

但问题变得更糟了,因为当选中一个标签时,我的主题应用的颜色(primary)被应用。

我的底部导航:

<com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottom_navigation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                app:menu="@menu/main_bottom_navigation"
                style="@style/BottomNavigationView"
                app:labelVisibilityMode="labeled"
                android:layout_alignParentBottom="true" />

我的一个选择器(适用于所有项目):

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Pressed state -->
    <item android:drawable="@drawable/bottom_bar_journal_on"
            android:color="@color/red_FF623E"
            android:state_checked="true"/>
    <!-- Default state -->
    <item android:drawable="@drawable/bottom_bar_journal_off"
            android:color="@color/background_yellow"
            android:state_checkable="false"/>

</selector>

我的菜单(我应用所有选择器的地方):
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
            android:id="@+id/action_journal"
            android:enabled="true"
            android:icon="@drawable/bottom_bar_journal"
            android:title="@string/main_menu_journal"
            app:showAsAction="withText" />

    <item
            android:id="@+id/action_measure"
            android:enabled="true"
            android:icon="@drawable/bottom_bar_measure_off"
            android:title="@string/main_menu_measure"
            app:showAsAction="withText" />

    <item
            android:id="@+id/action_add"
            android:enabled="false"
            android:title=""
            app:showAsAction="withText" />

    <item
            android:id="@+id/action_treatment"
            android:enabled="true"
            android:icon="@drawable/bottom_bar_treatment_off"
            android:title="@string/main_menu_treatment" />

    <item
            android:id="@+id/action_profile"
            android:enabled="true"
            android:icon="@drawable/bottom_bar_profile"
            android:title="@string/main_menu_profile"
            app:showAsAction="withText" />
</menu>
2个回答

8

底部导航栏通过app:itemIconTint覆盖图标颜色,但是从XML中删除该属性只会使导航栏使用应用程序的默认颜色。 为了防止导航栏应用颜色更改并使您的选择器按预期工作,您必须在代码中将图标着色列表设置为null,如下所示:

bottom_navigation_bar.itemIconTintList = null

编辑:我看到您想要对文本进行着色,这有点棘手。我能想到的唯一解决方案是忘记可绘制选择器,每次底部导航栏选择更改时替换该项的图标色调列表和文本颜色。在您的导航栏承载活动中,请定义这两个:

private val bottomNavBarStateList = arrayOf(
    intArrayOf(android.R.attr.state_checked),
    intArrayOf(-android.R.attr.state_checked)
)

private fun updateBottomNavBarColor(currentSelectedColor: Int) {
    val colorList = intArrayOf(
        ContextCompat.getColor(this, currentSelectedColor),
        ContextCompat.getColor(this, R.color.text_tertiary)
    )
    val colorStateList = ColorStateList(bottomNavBarStateList, colorList)
    bottom_navigation_bar.itemIconTintList = colorStateList
    bottom_navigation_bar.itemTextColor = colorStateList
}

然后在您导航栏的ItemSelectedListener中,调用updateBottomNavBarColor并使用您想要的颜色:

bottom_navigation_bar.setOnNavigationItemSelectedListener {
    when(it.itemId) {
        R.id.bottom_nav_action_treatment -> {
            updateBottomNavBarColor(R.color.treatment)
        }
        R.id.bottom_nav_action_profile -> {
            updateBottomNavBarColor(R.color.profile)
        }
        else -> {

        }
    }
}

这是完美的。我认为没有其他方法。 - TootsieRockNRoll
非常感谢这个答案,它帮助了我。 - Alex Rodionow

0

然后你可以在你的BottomNavigationView中像这样使用它:

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:itemIconTint="@drawable/bottom_navigation_colors"
app:itemTextColor="@drawable/bottom_navigation_colors"
app:menu="@menu/bottom_navigation_menu" />

app:itemIconTintapp:itemTextColor 都接受 ColorStateList,而不是单一的颜色。这意味着你可以编写一个选择器来响应选项的状态变化来定义这些颜色。

例如,你可以创建一个名为 bottom_navigation_colors.xml 的 ColorStateList 包含以下内容:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
      android:state_checked="true"
      android:color="@color/colorPrimary" />
  <item
      android:state_checked="false"
      android:color="@color/grey" />
 </selector>

使用了彩色材料风格

style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"

同时查看此链接:使用 Material 组件进行实践

也可以通过编程方式像这样改变颜色:

getMenuInflater().inflate(R.menu.menu_home, menu);
        Drawable drawable = menu.findItem(R.id.action_clear).getIcon();

        drawable = DrawableCompat.wrap(drawable);
        DrawableCompat.setTint(drawable, ContextCompat.getColor(this,R.color.textColorPrimary));
        menu.findItem(R.id.action_clear).setIcon(drawable);
        return true;

或者:

bottomNavigationView.setOnNavigationItemSelectedListener(
        new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.action_favorites:
                        //need change color of favotites here.
                    case R.id.action_schedules:

                    case R.id.action_music:

                }
                return true;
            }
        });

感谢您的时间。请看一下我的两张图片。如果我按照您的方式操作,当选中它们时,所有选项卡都会是相同的颜色。这不是我想要的。我需要每个选项卡在被选中时有不同的颜色。 - Itoun
你也可以通过编程的方式改变颜色。 getMenuInflater().inflate(R.menu.menu_home, menu); Drawable drawable = menu.findItem(R.id.action_clear).getIcon();drawable = DrawableCompat.wrap(drawable); DrawableCompat.setTint(drawable, ContextCompat.getColor(this,R.color.textColorPrimary)); menu.findItem(R.id.action_clear).setIcon(drawable); return true; - Jaspalsinh Gohil
你无法从对象“Item”编程设置颜色。 在您的菜单解决方案中,解决方案仅涉及可绘制项。这根本不是我想要的。 - Itoun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接