Estoy usando a TabLayout
con a ViewPager
y me pregunto cómo puedo cambiar de manera más eficiente el color del icono de la pestaña seleccionada en TabLayout.
Una referencia perfecta de cómo se implementa esto es la aplicación Youtube de Google . En la página principal, hay cuatro iconos de color gris oscuro. Cuando se selecciona una pestaña específica, el icono de la pestaña se vuelve blanco.
Sin bibliotecas de terceros , ¿cómo puedo lograr el mismo efecto?
Una posible solución es aparentemente con selectores. Pero en ese caso, tendría que encontrar una versión blanca y otra gris del ícono y luego cambiar el ícono cuando la pestaña se seleccione o deseleccione. Me pregunto si hay un método más eficaz en el que pueda simplemente resaltar el color del icono o algo así. No he podido encontrar esto en ningún tutorial.
EDITAR
La solución que menciono directamente arriba requiere el uso de dos elementos de diseño para el icono de cada pestaña. Me pregunto si hay alguna manera de hacerlo mediante programación con UN elemento de diseño para el icono de cada pestaña.
fuente
android-studio
etiqueta solo si es específica del IDE.Respuestas:
Encontré una forma que puede ser fácil.
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); } } );
fuente
Esto se puede hacer de manera muy simple, completamente en xml.
Agregue una línea a su TabLayout en su xml
app:tabIconTint="@color/your_color_selector"
, como se muestra a continuación:<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"/>
Luego, cree un archivo selector de color (llamado "your_color_selector.xml" arriba) en el directorio res / color:
<?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>
Esto supone que tiene 2 colores, "selected_color" y "unselected_color" en su archivo colors.xml.
fuente
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) { } }); }
fuente
setCurrentItem(0)
a una instancia de viewPager desde la actividad cuandoonBackButton()
se invoca el método, y el usuario siempre regresará al primer fragmento cuando intente salir de la aplicación.Puede utilizar un ColorStateList.
Primero, cree un archivo xml (por ejemplo
/color/tab_icon.xml
) que se vea así y defina los diferentes tonos para diferentes estados:<?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>
Luego agregue esto a su código:
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); } }
Primero, toma ColorStateList de su XML (el método sin tema está en desuso, pero es necesario para dispositivos anteriores a Marshmallow). Luego, establece para el ícono de cada pestaña es TintList en ColorStateList; use DrawableCompat (biblioteca de soporte) para admitir versiones anteriores también.
¡Eso es!
fuente
tabLayout
se haya inicializado TabLayout (named ).Para ello, tendrá que personalizar los iconos de las pestañas usando la clase de selector para cada pestaña como:
<?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" />
fuente
Agregue esto en el
res > colors
directorio:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:color="@android:color/holo_orange_dark"/> <item android:color="@android:color/holo_red_light"/> </selector>
Agregue código en la vista de pestaña en xml:
app:tabIconTint="@color/selector_tab"
fuente
¿Por qué no usas fuentes de iconos (como una fuente impresionante) para tus iconos? luego cambie la fuente del texto de la pestaña a su icono de fuente deseable .ttf y disfrute de cambiar el color del texto seleccionado a los iconos de su pestaña.
Yo mismo utilicé este método y es realmente agradable y limpio :)
en primer lugar, configure los títulos a partir de la fuente de iconos que desee:
en string.xml:
<string name="ic_calculator"></string> <string name="ic_bank"></string>
luego en 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); }
Entonces deberías cambiar la fuente de los títulos de las pestañas a 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); } } }
y por último, pero no menos importante, en su archivo .xml relacionado, establezca el color para su tabTextColor y 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.TabLayout>
y en 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>
fuente
compruebe el siguiente código. Personaliza tu icono, uno es de color y otro no es de 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)-->
fuente
En referencia a la segunda respuesta, que muestra cómo configurar el color por separado, muchas personas podrían preguntarse cómo eliminar el color del primer icono mientras se cambia al siguiente. Lo que puedes hacer es ir así:
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) { } });}
¡Habría comentado sobre la segunda respuesta pero no tenía suficiente reputación para eso! Lo siento. ¡Pero tenga en cuenta que se ahorrará tiempo y dolor de cabeza! Feliz aprendizaje
fuente
Puede usar
addOnTabSelectedListener
, funciona para mí.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) { } });
fuente
Una forma posible de "Resaltar" el icono es acceder a la vista de imagen y configurar el filtro de color. Intente usar el método ImageView setColorFilter (int color) y aplique el color blanco.
fuente
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {...}
Ha quedado obsoleto. Más bien usetabLayout.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) { } });
fuente
Extendiendo mi respuesta preferida con ColorStateList desde aquí , puede usar la siguiente solución si está usando pestañas personalizadas.
Configura pestañas en el xml de tu actividad
... <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> ...
Y diseño de pestaña personalizado 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>
En tu actividad
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");
Y agregue estas funciones auxiliares para el cambio de 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); }
Finalmente, el selector 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>
fuente
Verifique el siguiente código:
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) { } });
fuente
Puede cambiar el color del texto de la pestaña seleccionada utilizando el siguiente atributo xml del diseño de pestaña:
app:tabSelectedTextColor="your desired color"
Para personalizar el color de su icono de la pestaña seleccionada, debe usar el selector Crear un archivo xml en la carpeta dibujable:
<?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>
y agregue este selector al atributo xml de diseño de pestaña como se muestra a continuación:
app:tabIconTint="@drawable/name_of_file"
fuente
Realice los siguientes pasos respectivamente.
app / src / main / res / values / colors.xml (Agregar a colors.xml)
<color name="icon_enabled">#F3D65F</color> <color name="icon_disabled">#FFFFFF</color>
app / src / main / res / color / custom_tab_icon.xml (Crea una carpeta llamada color en res. Crea una pestaña personalizada icon.xml en la carpeta).
<?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 (Crear)
haga doble clic en action_settings para agregar
<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>
fuente