android android-viewpager android-tabs android-icons pagerslidingtabstrip

android - Agregar íconos a SlidingTabLayout en lugar de texto



android-viewpager android-tabs (11)

Amplíe su actividad principal desde FragmentActivity. También implemente esta clase desde ActionBar.TabListener ya que estamos agregando Tabs.

// Para agregar pestañas

for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setIcon(R.drawable.drawable_id) .setTabListener(this)); }

Chequea here

Estoy implementando un SlidingTabLayout en mi aplicación de Android. Mi consulta es que me gustaría implementar íconos en mis Pestañas deslizantes en lugar de textos para la navegación. Busqué mucho en Internet por cualquier tutorial o muestra, pero no encontré ninguno. También busqué una pregunta anterior en stackoverflow: Over Here - SlidingTabLayout with Icons . Fue un poco informativo pero realmente no me ayudó.

Para ser claro. Requiero que mis pestañas consten de íconos solamente . Sin texto.

Como soy nuevo en toda esta configuración, le agradecería que publicara el código correcto con una explicación. ¡Gracias por tu tiempo y esfuerzo!

PD También escuché sobre la pagerslidingtabstrip por Andreaz Stuetz y me pregunté si eso sería más adecuado para el tipo de cosas que voy a ...

También: Aquí es cómo me gustaría que se vieran mis pestañas deslizantes. Echa un vistazo a la parte superior de esta imagen.

EDITAR: AHORA QUE LOLLIPOP (CON DISEÑO DE MATERIAL) HA SALIDO. HE VISTO MUCHAS APLICACIONES UTILIZANDO UN NUEVO "ICONO" DE SLIDING-TAB-LAYOUT DE SLIDING-TAB-LAYOUT DISTANCIA DEBAJO DE SU BARRA DE HERRAMIENTAS (ANDROID 5.0 ​​ACTION-BAR). ¿ES SU NUEVA FORMA DE IMPLEMENTAR ESTO? ¡GRACIAS UNA VEZ MÁS!


El solo hecho de devolver null desde el método getPageTitle() hizo por mí:

@Override public CharSequence getPageTitle(int position) { return null; }


La clave para esto es devolver un SpannableString, que contiene su ícono en un ImageSpan, del método getPageTitle (posición) de su PagerAdapter:

private int[] imageResId = { R.drawable.ic_tab_notifications, R.drawable.ic_tab_weather, R.drawable.ic_tab_calendar }; @Override public CharSequence getPageTitle(int position) { Drawable image = getResources().getDrawable(imageResId[position]); image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); SpannableString sb = new SpannableString(" "); ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM); sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sb; }

Normalmente esto sería suficiente, pero la pestaña predeterminada creada por SlidingTabLayout hace una llamada a TextView#setAllCaps(true) que desactiva efectivamente todos los ImageSpans, por lo que tendrá que usar una vista de pestaña personalizada en su lugar:

res / layout / custom_tab.xml

<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12sp" android:textStyle="bold" android:background="?android:selectableItemBackground" android:padding="16dp" />

y en cualquier lugar que configure / enlace a su ViewPager:

SlidingTabLayout slidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs); slidingTabLayout.setCustomTabView(R.layout.custom_tab, 0); slidingTabLayout.setViewPager(viewPager);

(asegúrese de llamar a setCustomTabView antes de setViewPager )


Ok ... hay muchas maneras de implementar este cambio. Este es el más rápido y sucio, solo por la idea ..

Sustituya el método SlidingTabLayout.populateTabStrip () por esto ..

private void populateTabStrip() { final OnClickListener tabClickListener = new TabClickListener(); View tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_notif_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_weather_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_calendar_icon_only, mTabStrip, false); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView);

Cree cada diseño de esta manera LinearLayout> Elementos de ImageView, src apuntando al icono ...


Para personalizar SlidingTabLayout de la forma que desee, solo necesita modificar el método populateTabStrip ():

public void populateTabStrip() { final PagerAdapter adapter = mViewPager.getAdapter(); final View.OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_layout, mTabStrip, false); ImageView iconImageView = (ImageView) tabView.findViewById(R.id.tab_layout_icon); iconImageView.setImageDrawable(getContext().getResources().getDrawable(getIconResourceArray()[i])); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); } }

Tu diseño podría ser algo así:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="75dp" android:paddingTop="15dp" android:layout_height="50dp" android:orientation="vertical"> <ImageView android:id="@+id/tab_layout_icon" android:layout_width="20dp" android:layout_height="20dp" android:layout_gravity="center" /> </LinearLayout>

La forma en que implementes el método getResourceArray () depende de ti. Así es como lo hice:

public class IconSlidingTabLayout extends HorizontalScrollView { private Integer[] mIconResourceArray; ... public Integer[] getIconResourceArray() { return mIconResourceArray; } public void setIconResourceArray(Integer[] mIconResourceArray) { this.mIconResourceArray = mIconResourceArray; } }

En la actividad:

mSlidingTabLayout = (IconSlidingTabLayout) findViewById(R.id.icon_sliding_tab_layout); Integer[] iconResourceArray = { R.drawable.news_tab_icon, R.drawable.challenges_tab_icon, R.drawable.trophies_tab_icon, R.drawable.leaderboard_tab_icon }; mSlidingTabLayout.setIconResourceArray(iconResourceArray);

Tenga en cuenta que para tener acceso a R.layout.tab_layout *, debe importar su paquete.R en lugar de android.R como está por defecto en SlidingTabStrip.


Recientemente implementé esta biblioteca llamada ViewPagerAddons . Incluye SlidingTabLayoutColors , que es exactamente lo que necesitas. Simplemente deje que su adaptador de buscapersonas implemente la interfaz de SlidingTabLayouColors.ImageProvider , anule el método getPageImage y devuelva los identificadores de recursos de imagen según las posiciones de la página. Sencillo.

Aquí está el enlace a la biblioteca (instrucciones de configuración incluidas): https://bitbucket.org/enthusiast94/viewpageraddons/src


Resolví el mismo problema, pero también cambiando el dibujo en la pestaña seleccionada.

Crea tus dibujables para pestañas, con dos estados. first_tab_drawable.xml, second_tab_drawable.xml, third_tab_drawable.xml:

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

Cree su propio adaptador de buscapersonas, que se extiende desde PagerAdapter:

public class MyPagerAdapter extends PagerAdapter { private int[] drawablesIds = { R.drawable.first_tab_drawable, R.drawable.second_tab_drawable, R.drawable.third_tab_drawable }; //Constructor and other standard funcs... public int getDrawableId(int position){ //Here is only example for getting tab drawables return drawablesIds[position]; } //... }

Cambiar código de SlidingTabLayout:

private void populateTabStrip() { //Here is no more standard PagerAdapter! final MyPagerAdapter adapter = (MyPagerAdapter) mViewPager.getAdapter(); final View.OnClickListener tabClickListener = new TabClickListener(); for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; TextView tabTitleView = null; if (mTabViewLayoutId != 0) { // If there is a custom tab view layout id set, try and inflate it tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { tabView = createDefaultTabView(getContext()); } if (tabTitleView == null && TextView.class.isInstance(tabView)) { tabTitleView = (TextView) tabView; } //Set icon, that can be changeable instead setting text. //I think the text also can setting here from getPageTitle func. //But we interesting only in icon tabTitleView.setCompoundDrawablesWithIntrinsicBounds(adapter.getDrawableId(i), 0, 0, 0); //Select tab if it is current if (mViewPager.getCurrentItem() == i){ tabView.setSelected(true); } tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); } }

Y haga realmente seleccionado el título de TextView también en SlidingTabLayout en InternalViewPagerListener:

@Override public void onPageSelected(int position) { //Clear old selection and make new for(int i = 0; i < mTabStrip.getChildCount(); i ++){ mTabStrip.getChildAt(i).setSelected(false); } mTabStrip.getChildAt(position).setSelected(true); if (mScrollState == ViewPager.SCROLL_STATE_IDLE) { mTabStrip.onViewPagerPageChanged(position, 0f); scrollToTab(position, 0); } if (mViewPagerPageChangeListener != null) { mViewPagerPageChangeListener.onPageSelected(position); } }

Espero que sea de ayuda para alguien.


Sé que este hilo es bastante antiguo, pero quería compartir mi solución a este problema, porque podría ser útil para algunos. Funciona bastante bien, incluso para diferentes dibujables dependiendo del estado seleccionado.

Primero, SlidingTabLayout dos matrices dentro de la clase SlidingTabLayout (esto podría fácilmente ser subcontratado a otra clase):

private int[] imageResId = { R.drawable.multi_random, R.drawable.single_random, R.drawable.known_person, }; private int[] imageResSelected = { R.drawable.multi_random_selected, R.drawable.single_random_selected, R.drawable.known_person_selected }; private int mOldPosition = 0;

Ahora alteramos el método populateTabStrip() dentro de SlidingTabLayout :

for (int i = 0; i < adapter.getCount(); i++) { View tabView = null; ImageView tabImageView = null; if (mTabViewLayoutId != 0) { // HAS TO BE SET FOR THE MOMENT! // If there is a custom tab view layout id set, try and inflate it tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false); tabImageView = (ImageView) tabView.findViewById(mTabViewTextViewId); } if (tabView == null) { tabView = createDefaultTabView(getContext()); } if (tabImageView == null && ImageView.class.isInstance(tabView)) { tabImageView = (ImageView) tabView; } int resourceId; if (i == mViewPager.getCurrentItem()) { resourceId = imageResSelected[i]; mOldPosition = i; } else { resourceId = imageResId[i]; } tabImageView.setImageResource(resourceId); tabView.setOnClickListener(tabClickListener); mTabStrip.addView(tabView); }

Para actualizar la imagen según la pestaña seleccionada, agregamos algunas líneas al método onPageSelected

// This Method is called once the transition is finished // Change the drawable of the old one.. ImageView view = (ImageView) mTabStrip.getChildAt(mOldPosition); view.setImageResource(imageResId[mOldPosition]); // And now change it of the current one view = (ImageView) mTabStrip.getChildAt(position); view.setImageResource(imageResSelected[position]); mOldPosition = position;

Finalmente necesitamos agregar una vista de pestaña personalizada:

mSlidingTabLayout.setCustomTabView(R.layout.custom_tab, 0);

Como éste

<?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="16dp" android:layout_weight="1" android:src="@drawable/multi_random" />

Esta solución está lejos de ser perfecta, pero funciona para mis necesidades. Tal vez podría ayudar a alguien con esto.


Seguí la respuesta de Jeremy y está funcionando bien. AFAIK no hay una nueva forma de hacer esto. La mayoría de las aplicaciones ahora están eliminando la barra de herramientas por completo y añadiendo una tira deslizante personalizada recomendada por google.

Si usted tiene alguna pregunta específica, hágamelo saber. Tengo mi aplicación muy parecida a la captura de pantalla que has publicado. Creo que esta actualización de diseño de material se centró más en habilitar animaciones y efectos personalizados.


Su adaptador debe implementar PagerSlidingTabStrip.IconTabProvider .

Luego, en getPageIconResId puede devolver el id del recurso de imagen:

public class ViewPagerAdapter extends FragmentPagerAdapter implements PagerSlidingTabStrip.IconTabProvider { private static final int[] icons = {R.drawable.image1, R.drawable.image2, R.drawable.image3}; @Override public int getPageIconResId(int i) { return icons[i]; } }

Tenga en cuenta que solo se mostrará la imagen, el texto no.