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

Ito*_*oun 4 xml android bottomnavigationview material-components material-components-android

我试图让底部导航有点棘手。事实上我想要这种底部导航: 底部导航_1 底部导航_2 每个选项卡在被选中时都有不同的颜色。例如,选择时度量将呈红色(图标和标题),选择时配置文件将呈绿色...
所以我尝试为每个项目使用选择器(在我的菜单中),
但未应用颜色。图标更改成功(我尝试在选择某个项目时放置一个完全不同的图标),但选项卡标题的颜色没有更改。
我尝试从底部导航中删除 2 个属性:

app:itemTextColor="@color/black"
app:itemIconTint="@color/black"
Run Code Online (Sandbox Code Playgroud)

但情况变得更糟,因为选择选项卡时应用了我的主题应用程序(主要)的颜色。

我的底部导航:

<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" />
Run Code Online (Sandbox Code Playgroud)

我的选择器之一(逻辑应用于所有项目):

<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>
Run Code Online (Sandbox Code Playgroud)

和我的菜单(我应用所有选择器的地方):

<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>
Run Code Online (Sandbox Code Playgroud)

SVM*_*SVM 8

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

bottom_navigation_bar.itemIconTintList = null
Run Code Online (Sandbox Code Playgroud)

编辑:我看到你也想给文本着色,这有点棘手。我能想到的唯一解决方案是忘记可绘制选择器,只需在每次底部导航栏选择发生变化时替换项目的图标色调列表和文本颜色。在您的导航栏托管活动中,定义这两个:

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
}
Run Code Online (Sandbox Code Playgroud)

然后在导航栏的 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 -> {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)