Java 如何更改 TabLayout 所选选项卡的图标颜色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34562117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:46:56  来源:igfitidea点击:

How do I change the color of icon of the selected tab of TabLayout?

javaandroidmobilematerial-designandroid-tablayout

提问by wayway

I'm using a TabLayoutwith a ViewPagerand I'm wondering how I can most efficiently change the color of the icon of the selected tab in the TabLayout.

我正在使用 a TabLayoutViewPager我想知道如何最有效地更改 TabLayout 中所选选项卡的图标颜色。

A perfect reference for how this is implemented is Google's Youtube app. On the main page, there are four icons that are colored dark gray. When a specific tab is selected, the tab's icon becomes white.

Google 的 Youtube 应用程序是如何实现这一点的完美参考。在主页面上,有四个深灰色图标。选择特定选项卡后,该选项卡的图标变为白色。

Without any third party libraries, how can I achieve the same effect?

没有任何第三方库,如何达到同样的效果?

One possible solution is apparently with selectors.But in that case, I would have to find both a white and a gray version of the icon and then switch the icon when the tab becomes selected or deselected. I'm wondering if there's a more effective method where I can just highlight the icon color or something. I haven't been able to find this in any tutorial.

一种可能的解决方案显然是使用选择器。但在这种情况下,我必须找到图标的白色和灰色版本,然后在选项卡被选中或取消选中时切换图标。我想知道是否有更有效的方法可以突出显示图标颜色或其他东西。我在任何教程中都找不到这个。

EDIT

编辑

The solution that I mention directly above requires the use of two drawables for each tab's icon. I'm wondering if there's a way I can do it programmatically with ONEdrawable for each tab's icon.

我在上面直接提到的解决方案需要为每个选项卡的图标使用两个可绘制对象。我想知道是否有一种方法可以为每个选项卡的图标以编程方式使用ONEdrawable 来完成。

回答by Yaw Asare

One possible way of "Highlighting" the icon is to access the image view and set the color filter. Try using the setColorFilter(int color) ImageView method and applying the color white.

“突出显示”图标的一种可能方法是访问图像视图并设置滤色器。尝试使用 setColorFilter(int color) ImageView 方法并应用白色。

回答by Anshul Tyagi

For it You'll have to customize tab icons using selector class for each Tab like:

为此,您必须使用每个选项卡的选择器类自定义选项卡图标,例如:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/advisory_selected" android:state_selected="true" />
<item android:drawable="@drawable/advisory_normal" android:state_selected="false" />

回答by Prathap Badavath

check the following code. Customise your icon one is color and another one is no color.

检查以下代码。自定义您的图标,一个是彩色的,另一个是没有颜色的。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/mybookings_select" android:state_selected="true"/><!-- tab is selected(colored icon)-->
<item android:drawable="@drawable/mybookings" /><!-- tab is not selected(normal no color icon)-->

回答by par4301

Why don't you use icon fonts (like font awesome) for your icons? then change the font of tab text to your desirable font icon .ttf and enjoy change selected text color to your tab icons!

你为什么不为你的图标使用图标字体(比如字体真棒)?然后将标签文本的字体更改为您想要的字体图标 .ttf 并享受将所选文本颜色更改为您的标签图标的乐趣!

I, myself, used this method and it is really nice and clean :)

我,我自己,使用了这种方法,它真的很好很干净:)

firstly, set up the titles from your desired icon font:

首先,从您想要的图标字体设置标题:

in string.xml:

在 string.xml 中:

    <string name="ic_calculator">&#xf1ec;</string>
    <string name="ic_bank">&#xf19c;</string>

then in MainActivity.Java:

然后在 MainActivity.Java 中:

    private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new FragmentBank(), getString(R.string.ic_bank));
    adapter.addFragment(new FragmentCalculate(), getString(R.string.ic_calculator));
    viewPager.setAdapter(adapter);
    }

Then you should change the font of Tab titles to font-awesome:

然后你应该将 Tab 标题的字体更改为 font-awesome:

    Typeface typeFaceFont = Typeface.createFromAsset(getAssets(), "fontawesome-webfont.ttf");

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
    int tabsCount = vg.getChildCount();
    for (int j = 0; j < tabsCount; j++) {
        ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
        int tabChildsCount = vgTab.getChildCount();
        for (int i = 0; i < tabChildsCount; i++) {
            View tabViewChild = vgTab.getChildAt(i);
            if (tabViewChild instanceof TextView) {
                ((TextView) tabViewChild).setTypeface(typeFaceFont);
            }
        }
    }

and last but not least, in your related .xml file, set color for your tabTextColor and tabSelectedTextColor:

最后但并非最不重要的是,在相关的 .xml 文件中,为 tabTextColor 和 tabSelectedTextColor 设置颜色:

<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="horizontal"
        android:background="@color/colorPrimaryDark"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextColor="@color/textColorPrimary"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabMode="fixed"
        app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>

and in colors.xml:

并在colors.xml中:

<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorHighlight">#FFFFFF</color>
    <color name="textColorPrimary">#E1E3F3</color>
</resources>

回答by Cristian Hoyos

I found a way that can be easy.

我找到了一种简单的方法。

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);

    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setOnTabSelectedListener(
            new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {

                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    super.onTabSelected(tab);
                    int tabIconColor = ContextCompat.getColor(context, R.color.tabSelectedIconColor);
                    tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
                }

                @Override
                public void onTabUnselected(TabLayout.Tab tab) {
                    super.onTabUnselected(tab);
                    int tabIconColor = ContextCompat.getColor(context, R.color.tabUnselectedIconColor);
                    tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
                }

                @Override
                public void onTabReselected(TabLayout.Tab tab) {
                    super.onTabReselected(tab);
                }
            }
    );

回答by Nurcahyadin

private void setupTabIcons() {
    tabLayout.getTabAt(0).setIcon(tabIcons[0]);
    tabLayout.getTabAt(1).setIcon(tabIcons[1]);
    tabLayout.getTabAt(2).setIcon(tabIcons[2]);
    tabLayout.getTabAt(3).setIcon(tabIcons[3]);

    tabLayout.getTabAt(0).getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
    tabLayout.getTabAt(1).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
    tabLayout.getTabAt(2).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
    tabLayout.getTabAt(3).getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);


    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            tab.getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);

        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            tab.getIcon().setColorFilter(Color.parseColor("#a8a8a8"), PorterDuff.Mode.SRC_IN);
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
}

回答by Felix Edelmann

You can use a ColorStateList.

您可以使用 ColorStateList。

First, create an xml file (e.g. /color/tab_icon.xml) that looks like this and defines the different tints for different states:

首先,创建一个如下所示的 xml 文件(例如/color/tab_icon.xml),并为不同的状态定义不同的色调:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/icon_light"
        android:state_selected="true" />

    <item android:color="@color/icon_light_inactive" />
</selector>

Then add this to your code:

然后将其添加到您的代码中:

ColorStateList colors;
if (Build.VERSION.SDK_INT >= 23) {
    colors = getResources().getColorStateList(R.color.tab_icon, getTheme());
}
else {
    colors = getResources().getColorStateList(R.color.tab_icon);
}

for (int i = 0; i < tabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    Drawable icon = tab.getIcon();

     if (icon != null) {
        icon = DrawableCompat.wrap(icon);
        DrawableCompat.setTintList(icon, colors);
    }
}

First, you grab the ColorStateList from your XML (the method without theme is deprecated, but necessary for pre-Marshmallow devices). Then you set for each tab's icon it's TintList to the ColorStateList; use DrawableCompat (support library) to support older versions as well.

首先,从 XML 中获取 ColorStateList(不推荐使用没有主题的方法,但对于 Marshmallow 之前的设备是必需的)。然后你为每个选项卡的图标设置它的 TintList 到 ColorStateList;使用 DrawableCompat(支持库)也支持旧版本。

That's it!

就是这样!

回答by Alok

On reference to the second answer which shows how to set color separately, many people might be wondering around how to remove the color of the first icon while switching to next one. What you can do is go like this :

关于显示如何单独设置颜色的第二个答案,许多人可能想知道如何在切换到下一个图标时删除第一个图标的颜色。你可以做的是这样:

private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
tabLayout.getTabAt(3).setIcon(tabIcons[3]);

tabLayout.getTabAt(0).getIcon().setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(1).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(2).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
tabLayout.getTabAt(3).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);


tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        tab.getIcon().setColorFilter(Color.GREEN,PorterDuff.Mode.SRC_IN);

    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
        //for removing the color of first icon when switched to next tab
        tablayout.getTabAt(0).getIcon().clearColorFilter();
        //for other tabs
        tab.getIcon().clearColorFilter();

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});}

I would have commented on the second answer but did not have enough reputations for that! Sorry. But please follow that you'd save your time and your headache! Happy learning

我会评论第二个答案,但没有足够的声誉!对不起。但是请注意,您可以节省时间和头痛!快乐学习

回答by NikiFo

Extending my prefered answer with the ColorStateList from here, you can use the following solution if you are using custom tabs.

使用此处的 ColorStateList 扩展我的首选答案,如果您使用自定义选项卡,则可以使用以下解决方案。

Set up tabs in your activity's xml

在活动的 xml 中设置选项卡

 ...

<android.support.design.widget.TabLayout
    android:id="@+id/main_tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.design.widget.TabItem
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/nav_bar_tab_item"/>

    <android.support.design.widget.TabItem
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout="@layout/nav_bar_tab_item"/>
</android.support.design.widget.TabLayout>

...

And custom tab layout nav_bar_item.xml

和自定义选项卡布局 nav_bar_item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/nav_bar_item_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingEnd="@dimen/_5sdp"
android:paddingStart="@dimen/_5sdp">

<ImageView
    android:id="@+id/item_img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

<TextView
    android:id="@+id/item_description"
    android:layout_width="wrap_content"
    android:gravity="center"

<!-- Use selector here to change the text color when selected/unselected -->
    android:textColor="@color/nav_bar_icons_color"

    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/item_img"/>

</android.support.constraint.ConstraintLayout>

In your activity

在您的活动中

    tabLayout = findViewById(R.id.main_tablayout);

    ConstraintLayout navMyHotelLayout = (ConstraintLayout) tabLayout.getTabAt(0)
            .getCustomView();
    tab1Icon = navMyHotelLayout.findViewById(R.id.item_img);
    tab1TextView = navMyHotelLayout.findViewById(R.id.item_description);

    tab1Icon.setImageResource(R.drawable.ic_tab1);

    // Use the selector here to change the color when selected/unselected
    tintImageViewSelector(tab1Icon, R.color.nav_bar_icons_color);

    tab1TextView.setText("tab 1");

    ConstraintLayout navTtdLayout = (ConstraintLayout) tabLayout.getTabAt(1)
            .getCustomView();
    tab2Icon = navTtdLayout.findViewById(R.id.item_img);
    tab2View = navTtdLayout.findViewById(R.id.item_description);

    tab2Icon.setImageResource(R.drawable.ic_tab2);
    tintImageViewSelector(tab2Icon, R.color.nav_bar_icons_color);
    tab2TextView.setText("tab 2");

And add these helper functions for the change of color

并添加这些颜色变化的辅助函数

public static void tintDrawableSelector(Drawable vd, final @ColorRes int clrRes, Context context) {

    DrawableCompat.setTintList(vd, ContextCompat.getColorStateList(context, clrRes));
}

public static void tintImageViewSelector(ImageView imgView, final @ColorRes int clrRes, Context context) {

    tintDrawableSelector(imgView.getDrawable(), clrRes);
}

Finally, the selector nav_bar_icons_color.xml

最后,选择器 nav_bar_icons_color.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="@android:color/white" android:state_selected="true"/>
    <item android:color="@android:color/black"/>
</selector>

回答by Vin Norman

This can be done very simply, entirely in xml.

这可以非常简单地完成,完全在 xml 中。

Add one line to your TabLayout in your xml, app:tabIconTint="@color/your_color_selector", as below:

在 xml 中向 TabLayout 添加一行app:tabIconTint="@color/your_color_selector",如下所示:

 <android.support.design.widget.TabLayout
     android:id="@+id/tab_layout"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     app:tabIconTint="@color/your_color_selector"
     app:tabIndicatorColor="@color/selected_color"/>

Then, create a color selector file (named "your_color_selector.xml" above) in res/color directory:

然后,在 res/color 目录中创建一个颜色选择器文件(上面命名为“your_color_selector.xml”):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/selected_color" android:state_selected="true"/>
    <item android:color="@color/unselected_color"/>
</selector>

This assumes you have 2 colors, "selected_color" and "unselected_color" in your colors.xml file.

这假设您的colors.xml 文件中有2 种颜色,“selected_color”和“unselected_color”。