Как изменить цвет значка выбранной вкладки TabLayout?

Я использую TabLayout с ViewPager и мне интересно, как я могу наиболее эффективно изменить цвет значка выбранной вкладки в TabLayout.

Идеальная ссылка на то, как это реализовано, – это приложение Youtube от Google . На главной странице есть четыре значка, которые окрашены в темно-серый цвет. Когда выбрана конкретная вкладка, значок вкладки становится белым.

Без каких-либо сторонних библиотек , как я могу добиться такого же эффекта?

Одно из возможных решений, по-видимому, с селекторами. Но в этом случае мне нужно будет найти и белую, и серая версию значка, а затем переключить значок, когда вкладка будет выбрана или отменена. Мне интересно, есть ли более эффективный метод, где я могу просто выделить цвет значка или что-то в этом роде. Я не смог найти это в любом учебнике.

РЕДАКТИРОВАТЬ

Решение, которое я упоминаю непосредственно выше, требует использования двух чертежей для каждой вкладки. Мне интересно, есть ли способ сделать это программно с ONE для каждого значка вкладки.

Solutions Collecting From Web of "Как изменить цвет значка выбранной вкладки TabLayout?"

Я нашел способ, который может быть легким.

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

Во-первых, вы берете ColorStateList из своего XML (метод без темы устарел, но необходим для устройств с предварительным указателем Marshmallow). Затем вы устанавливаете для значка каждой вкладки это TintList для ColorStateList; Используйте DrawableCompat (библиотеку поддержки) для поддержки более старых версий.

Это оно!

Для этого вам нужно будет настроить значки вкладок, используя селекторный класс для каждой вкладки, например:

 <?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" /> 

Почему бы вам не использовать значки шрифтов (например, шрифт awesome) для ваших значков? Затем измените шрифт текста вкладки на желаемый значок шрифта .ttf и получите возможность изменить выбранный цвет текста на свои значки вкладок!

Я сам использовал этот метод, и он действительно приятный и чистый 🙂

Во-первых, настройте заголовки с нужного шрифта значка:

В string.xml:

  <string name="ic_calculator">&#xf1ec;</string> <string name="ic_bank">&#xf19c;</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 на шрифт-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> 

Проверьте следующий код. Настроить свой значок – цвет, а другой – не цвет.

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

Одним из возможных способов «выделения» значка является доступ к представлению изображения и установка цветового фильтра. Попробуйте использовать метод ImageColorFilter (int color) ImageView и примените белый цвет.

Что касается второго ответа, который показывает, как устанавливать цвет отдельно, многие люди могут задаться вопросом, как удалить цвет первого значка при переключении на следующий. Что вы можете сделать, так это:

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

Я бы прокомментировал второй ответ, но для этого не хватило репутации! Сожалею. Но, пожалуйста, следуйте за тем, чтобы вы сэкономили свое время и головную боль! Счастливое обучение