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
How do I change the color of icon of the selected tab of TabLayout?
提问by wayway
I'm using a TabLayout
with a ViewPager
and I'm wondering how I can most efficiently change the color of the icon of the selected tab in the TabLayout.
我正在使用 a TabLayout
,ViewPager
我想知道如何最有效地更改 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"></string>
<string name="ic_bank"></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”。