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.
Verifique este enlace de solución en androidhive sobre las pestañas / viewpager de diseño de materiales
Un muy buen sitio web sobre soluciones de Android. Espero que encuentres una solución.