我正在使用带有TabLayout
的ViewPager
,我想知道如何最有效地更改TabLayout中所选标签图标的颜色。
谷歌的Youtube应用程序是如何实现这一功能的完美参考。在主页面上,有四个图标为深灰色。选择特定选项卡后,选项卡的图标将变为白色。
没有任何第三方库,我怎样才能达到同样的效果?
一种可能的解决方案显然是选择器。但在这种情况下,我必须找到图标的白色和灰色版本,然后在选中或取消选择选项卡时切换图标。我想知道是否有更有效的方法我可以突出显示图标颜色或其他东西。我在任何教程中都找不到这个。
编辑
我上面直接提到的解决方案需要为每个标签的图标使用两个drawable。我想知道是否有一种方法可以通过一个drawable为每个标签的图标以编程方式进行。
我找到了一种方便的方法。
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);
}
}
);
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {...}
已被弃用。而是使用
tabLayout.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
int tabIconColor = ContextCompat.getColor(context, R.color.tabSelectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
int tabIconColor = ContextCompat.getColor(context, R.color.tabUnselectedIconColor);
tab.getIcon().setColorFilter(tabIconColor, PorterDuff.Mode.SRC_IN);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
检查以下代码:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if(tab.getPosition() == 0){
tabLayout.getTabAt(0).setIcon(tabIcons1[0]);
}
if(tab.getPosition() == 1){
tabLayout.getTabAt(1).setIcon(tabIcons1[1]);
}
if(tab.getPosition() == 2){
tabLayout.getTabAt(2).setIcon(tabIcons1[2]);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
你可以使用addOnTabSelectedListener
,它适合我。
tablayout = findViewById(R.id.viewall_tablayout);
pager = findViewById(R.id.viewall_pager);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragments(new RestFragment(),"Restaurant");
adapter.addFragments(new BarFragment(),"Bar");
adapter.addFragments(new HotelFragment(),"Hotel");
adapter.addFragments(new CoffeeFragment(),"Coffee Shop");
pager.setAdapter(adapter);
tablayout.setupWithViewPager(pager);
tablayout.getTabAt(0).setIcon(R.drawable.ic_restaurant);
tablayout.getTabAt(1).setIcon(R.drawable.ic_glass_and_bottle_of_wine);
tablayout.getTabAt(2).setIcon(R.drawable.ic_hotel_black_24dp);
tablayout.getTabAt(3).setIcon(R.drawable.ic_hot_coffee);
tablayout.getTabAt(0).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(1).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(2).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.getTabAt(3).getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getIcon().setTint(getResources().getColor(R.color.colorPrimary,getTheme()));
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
tab.getIcon().setTint(getResources().getColor(R.color.colorAccent,getTheme()));
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
使用here中的ColorStateList扩展我的首选答案,如果您使用自定义选项卡,则可以使用以下解决方案。
在活动的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>
...
并自定义选项卡布局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>
在你的活动中
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");
并添加这些辅助函数以改变颜色
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);
}
最后,选择器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>
您可以使用Tab布局的以下xml属性更改所选选项卡的文本颜色:
app:tabSelectedTextColor="your desired color"
要自定义所选选项卡的图标颜色,您需要使用选择器在drawable文件夹下创建一个xml文件:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="selected_item_color" android:state_activated="true" />
<item android:color="unselected_item_color" />
</selector>
并将此选择器添加到选项卡布局xml属性,如下所示:
app:tabIconTint="@drawable/name_of_file"
app / src / main / res / values / colors.xml(添加到colors.xml)
<color name="icon_enabled">#F3D65F</color>
<color name="icon_disabled">#FFFFFF</color>
app / src / main / res / color / custom_tab_icon.xml(在res中创建一个名为color的文件夹。在文件夹中创建一个自定义选项卡icon.xml。)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/icon_enabled" android:state_selected="true"/>
<item android:color="@color/icon_disabled" android:state_selected="false"/>
</selector>
app / src / main / res / drawable / ic_action_settings.png(创建)
双击action_settings添加
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="21.6"
android:viewportHeight="21.6"
android:tint="@color/custom_tab_icon">
<group android:translateX="-1.2"
android:translateY="-1.2">
<path
android:fillColor="#FF000000"
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
</group>
</vector>
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) {
}
});
}
您可以使用ColorStateList。
首先,创建一个看起来像这样的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>
然后将其添加到您的代码中:
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);
}
}
首先,从XML中获取ColorStateList(不使用主题的方法,但对于Marshmallow之前的设备是必需的)。然后为每个选项卡的图标设置它的TintList到ColorStateList;使用DrawableCompat(支持库)也支持旧版本。
而已!
这可以非常简单地完成,完全用xml完成。
在xml,app:tabIconTint="@color/your_color_selector"
中的TabLayout中添加一行,如下所示:
<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"/>
然后,在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>
假设您在colors.xml文件中有两种颜色“selected_color”和“unselected_color”。
对于它你必须为每个Tab使用选择器类自定义选项卡图标,如:
<?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" />
检查以下代码。自定义您的图标一个是颜色而另一个是没有颜色。
<?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)-->
为什么不为图标使用图标字体(如字体真棒)?然后将标签文本的字体更改为您想要的字体图标.ttf并享受将所选文本颜色更改为标签图标!
我,我自己,使用这种方法,它真的很干净:)
首先,从您想要的图标字体设置标题:
在string.xml中:
<string name="ic_calculator"></string>
<string name="ic_bank"></string>
然后在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);
}
然后你应该将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);
}
}
}
最后但并非最不重要的是,在相关的.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>
并在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>
在参考显示如何分别设置颜色的第二个答案时,许多人可能想知道如何在切换到下一个图标时删除第一个图标的颜色。你能做的就是这样:
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) {
}
});}
我会对第二个答案发表评论,但没有足够的声誉!抱歉。但请注意,这样可以节省您的时间和头痛!快乐学习
“突出显示”图标的一种可能方法是访问图像视图并设置颜色过滤器。尝试使用setColorFilter(int color)ImageView方法并应用白色。