【问题标题】:Android - Change color of icon and title of each tab bottom navigationAndroid - 更改每个标签底部导航的图标和标题颜色
【发布时间】:2020-02-25 14:45:27
【问题描述】:

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

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

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

我的底部导航:

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

【问题讨论】:

    标签: android xml bottomnavigationview material-components material-components-android


    【解决方案1】:

    底部导航栏通过 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 -> {
    
            }
        }
    }
    

    【讨论】:

    • 这是完美的。我觉得没有别的办法了
    • 感谢一百万的回答,它帮助了我
    【解决方案2】:

    你会在你的 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"
    

    还可以查看此链接:Hands-on with Material Components

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

    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;
                }
            });
    

    【讨论】:

    • 感谢您的宝贵时间。请看一下我的2张照片。如果我按照您的方式进行操作,那么当它们被选中时,我将拥有相同颜色的所有选项卡。那不是我想要的。选择时,我需要在每个选项卡上使用不同的颜色。
    • 您也可以通过编程方式更改颜色 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);返回真;
    • 您无法通过对象Item 以编程方式设置颜色。在您的菜单解决方案中,该解决方案仅与可绘制对象有关。这根本不是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2020-11-17
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多