Selección de pestaña TabLayout

Respuestas:

418

Si conoce el índice de la pestaña que desea seleccionar, puede hacerlo así:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();

Esta técnica funciona incluso si está usando el TabLayout por sí solo sin un ViewPager (que es atípico, y probablemente sea una mala práctica, pero lo he visto hecho).

Luciérnaga
fuente
10
Esta solución solo funciona si la pestaña se ha agregado a la barra de acción, lo que podría no ser siempre el caso. De la documentación para TabLayout.Tab.select(): "Seleccione esta pestaña. Solo válido si la pestaña se ha agregado a la barra de acción".
Daniel Kvist
77
@DanielKvist, en realidad la documentación en sí es incorrecta. El código fuente habla por sí mismo. Esta respuesta debe ser la respuesta aceptada.
Jason Sparc
@JasonSparc Hmm, recuerdo que no funcionó para mí la última vez que probé esta solución, pero veré si puedo verificar dos veces cómo funciona para mí. ¿Has probado? ¿Podría funcionar en algunos casos, mientras que no en otros? ¿Podría depender del nivel de API o algo similar?
Daniel Kvist
¡Gracias por aclarar el aire con respuestas a medias! Porque eso simplemente no funciona en TabLayout independiente probablemente por la razón que usted indicó; ¡Está destinado a funcionar con pestañas en Actionbar!
sud007
3
¿Por qué usar TabLayout sin ViewPager debería considerarse una mala práctica?
tomalf2
85

Así es como lo resolví:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}
salto
fuente
3
La respuesta seleccionada no funcionó para mí, pero esta sí.
Rafal Zawadzki el
gran solución! funcionó bien para mí, cuando necesitaba volver a la primera página tanto viewPager como TabView
sashk0
49

Utilizar este:

tabs.getTabAt(index).select();
Riyas PK
fuente
gracias, esta es una solución segura para mi implementación
islam farid
Objects.requireNonNull(tabs.getTabAt(position)).select();seguro de usar
Williaan Lopes
1
Tenga en cuenta que, si currentTabIndex e index son iguales, esto envía su flujo a onTabReselected y no onTabSelected.
Abhishek Kumar
@WilliaanLopes, esto no lo protegerá de NPI, solo lo lanzará antes
Krzysztof Kubicki
33

Utilizar este:

<android.support.design.widget.TabLayout
    android:id="@+id/patienthomescreen_tabs"
    android:layout_width="match_parent"
    android:layout_height="72sp"
    app:tabGravity="fill"
    app:tabMode="fixed"
    app:tabIndicatorColor="@android:color/white"
    app:tabSelectedTextColor="@color/green"/>

Después en OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Pravin Suthar
fuente
¿Qué pasa si el tabMode es desplazable?
GvSharma
Creo lo mismo, por favor, primero intenta eso.
Pravin Suthar
23

Probablemente esta no sea la solución definitiva , y requiere que uses el TabLayoutjunto con unViewPager , pero así es como lo resolví:

void selectPage(int pageIndex)
{
    viewPager.setCurrentItem(pageIndex);
    tabLayout.setupWithViewPager(viewPager);
}

Probé cuán grande es el impacto en el rendimiento del uso de este código mirando primero los monitores de CPU y memoria en Android Studio mientras ejecutaba el método, luego comparándolo con la carga que se puso en la CPU y la memoria cuando navegaba entre las páginas yo mismo (usando gestos de deslizamiento), y la diferencia no es significativamente grande, así que al menos no es una solución horrible ...

¡Espero que esto ayude a alguien!

Daniel Kvist
fuente
1
Cuando hice la solución de dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), cuando hice clic en la pestaña a la derecha, no actualizó la página de ViewPager (no sé por qué). Solo hacer clic de nuevo en la pestaña izquierda y luego en la pestaña derecha nuevamente actualizaría finalmente la página para que tenga la página de la pestaña derecha, lo cual es muy problemático. Pero esta solución no tenía problemas técnicos.
Rock Lee
12

Si no puede usar tab.select () y no quiere usar un ViewPager, aún puede seleccionar una pestaña mediante programación. Si está utilizando una vista personalizada TabLayout.Tab setCustomView(android.view.View view), es más simple. Aquí se explica cómo hacerlo en ambos sentidos.

// if you've set a custom view
void updateTabSelection(int position) {
    // get the position of the currently selected tab and set selected to false
    mTabLayout.getTabAt(mTabLayout.getSelectedTabPosition()).getCustomView().setSelected(false);
    // set selected to true on the desired tab
    mTabLayout.getTabAt(position).getCustomView().setSelected(true);
    // move the selection indicator
    mTabLayout.setScrollPosition(position, 0, true);

    // ... your logic to swap out your fragments
}

Si no está utilizando una vista personalizada, puede hacerlo así

// if you are not using a custom view
void updateTabSelection(int position) {
    // get a reference to the tabs container view
    LinearLayout ll = (LinearLayout) mTabLayout.getChildAt(0);
    // get the child view at the position of the currently selected tab and set selected to false
    ll.getChildAt(mTabLayout.getSelectedTabPosition()).setSelected(false);
    // get the child view at the new selected position and set selected to true
    ll.getChildAt(position).setSelected(true);
    // move the selection indicator
    mTabLayout.setScrollPosition(position, 0, true);

    // ... your logic to swap out your fragments
}

Use un StateListDrawable para alternar entre elementos de dibujo seleccionados y no seleccionados o algo similar para hacer lo que quiera con colores y / o elementos de diseño.

kenodoggy
fuente
12

Simplemente configure viewPager.setCurrentItem(index)y el TabLayout asociado seleccionaría la pestaña respectiva.

Panduka DeSilva
fuente
Esto no funcionó para mí. Tuve que usar el método .post.
arenaq
7

Puedes intentar resolverlo con esto:

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);

TabLayout.Tab tab = tabLayout.getTabAt(pos);
if (tab != null) {
    tab.select();
}
CoCo Dev
fuente
5

prueba esto

    new Handler().postDelayed(
            new Runnable(){
                @Override
                public void run() {
                    if (i == 1){
                        tabLayout.getTabAt(0).select();
                    } else if (i == 2){
                        tabLayout.getTabAt(1).select();
                    }
                }
            }, 100);
AGTHAMAYS
fuente
Gracias, funcionó para mí. ¿Pero es una buena práctica usar retrasado?
Harsh Shah
Supongo que es malo ejecutar un subproceso en cualquiera de los diseños porque si supone que está buscando el texto para la pestaña del servidor de fondo y si por alguna razón el servidor se retrasa, este subproceso del sistema consumirá los recursos de su dispositivo de manera poco frecuente.
cammando
solución tan fea
Lester
Esto no funciona para mi. ¿Cómo hago para que si el usuario hace clic en una pestaña, demore la selección de esa pestaña? No puedo hacer que nada funcione. En cambio, intenté si i == 1 usar (mViewPager.getCurrentItem () == 0) pero no funciona y tampoco lo hace nada más.
iBEK
5

Un poco tarde pero podría ser una solución útil. Estoy usando mi TabLayout directamente en mi Fragmento e intento seleccionar una pestaña bastante temprano en el Ciclo de vida del Fragmento. Lo que funcionó para mí fue esperar hasta que TabLayout terminara de dibujar sus vistas secundarias mediante el android.view.View#postmétodo. es decir:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
ahmed_khan_89
fuente
la respuesta correcta funcionó para mí, pero algún retraso le dará un buen efecto new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham
3

Yo estoy usando TabLayout para cambiar fragmentos. Funciona en su mayor parte, excepto que cada vez que intentaba seleccionar una pestaña mediante programación tab.select(), mi TabLayout.OnTabSelectedListeneractivaba el onTabSelected(TabLayout.Tab tab), lo que me causaba mucho dolor. Estaba buscando una manera de hacer una selección programática sin activar al oyente.

Así que adapté la respuesta de @kenodoggy a mi uso. Además, me enfrentaba a un problema en el que algunos de los objetos internos volverían nulos (porque aún no se habían creado, porque estaba respondiendo onActivityResult()desde mi fragmento, que ocurre antes onCreate()en el caso de que la actividad sea singleTasko singleInstance), así que escribí un detallado si / otra secuencia que informaría el error y se caería sin la NullPointerExceptionque de otra forma se dispararía Uso Timber para iniciar sesión, si no estás usando ese sustituto Log.e().

void updateSelectedTabTo(int position) {
    if (tabLayout != null){
        int selected = tabLayout.getSelectedTabPosition();
        if (selected != -1){
            TabLayout.Tab oldTab = tabLayout.getTabAt(0);
            if (oldTab != null){
                View view = oldTab.getCustomView();
                if (view != null){
                    view.setSelected(false);
                }
                else {
                    Timber.e("oldTab customView is null");
                }
            }
            else {
                Timber.e("oldTab is null");
            }
        }
        else {
            Timber.e("selected is -1");
        }
        TabLayout.Tab newTab = tabLayout.getTabAt(position);
        if (newTab != null){
            View view = newTab.getCustomView();
            if (view != null){
                view.setSelected(false);
            }
            else {
                Timber.e("newTab customView is null");
            }
        }
        else {
            Timber.e("newTab is null");
        }
    }
    else {
        Timber.e("tablayout is null");
    }
}

Aquí, tabLayout es mi variable de memoria vinculada al TabLayoutobjeto en mi XML. Y no uso la función de pestaña de desplazamiento, así que también la eliminé.

Dhiraj Gupta
fuente
3

debes usar viewPager para usar viewPager.setCurrentItem ()

 viewPager.setCurrentItem(n);
 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
Luis Muñoz
fuente
2

agregar para su visor:

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                array.clear();
                switch (position) {
                    case 1:
                        //like a example
                        setViewPagerByIndex(0);
                        break;
                }
            }

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

// en el controlador para evitar accidentes fuera de memoria

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}
Alex Zaraos
fuente
1
"Prevenir el bloqueo de memoria": ¿por qué necesitamos un hilo separado para seleccionar el elemento actual?
AppiDevo
2

Una solución combinada de diferentes respuestas es:

new Handler().postDelayed(() -> {

  myViewPager.setCurrentItem(position, true);

  myTabLayout.setScrollPosition(position, 0f, true);
},
100);
Zon
fuente
2

Con lo TabLayoutproporcionado por la Biblioteca de componentes de material, simplemente use el selectTabmétodo:

TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.selectTab(tabLayout.getTabAt(index));

ingrese la descripción de la imagen aquí

Requiere la versión 1.1.0.

Gabriele Mariotti
fuente
No, selectTab es un método privado de paquete.
XY
@ xyuber.com Agregué una información importante. Requiere la versión 1.1.0. El método es público ahora
Gabriele Mariotti
1

Por defecto, si selecciona una pestaña, se resaltará. Si desea seleccionar explícitamente significa usar el código comentado dado en onTabSelected (pestaña TabLayout.Tab) con su posición de índice de pestaña especificada. Este código explicará el fragmento de cambio en la posición seleccionada de la pestaña usando el visor.

public class GalleryFragment extends Fragment implements TabLayout.OnTabSelectedListener 
{
private ViewPager viewPager;public ViewPagerAdapter adapter;private TabLayout tabLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new PaymentCardFragment(), "PAYMENT CARDS");
adapter.addFragment(new LoyaltyCardFragment(), "LOYALTY CARDS");
viewPager.setAdapter(adapter);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setOnTabSelectedListener(this);
}

@Override
public void onTabSelected(TabLayout.Tab tab) {
    //This will be called 2nd when you select a tab or swipe using viewpager
    final int position = tab.getPosition();
    Log.i("card", "Tablayout pos: " + position);
    //TabLayout.Tab tabdata=tabLayout.getTabAt(position);
    //tabdata.select();
    tabLayout.post(new Runnable() {
        @Override
        public void run() {
            if (position == 0) {
                PaymentCardFragment paymentCardFragment = getPaymentCardFragment();
                if (paymentCardFragment != null) {
                   VerticalViewpager vp = paymentCardFragment.mypager;
                    if(vp!=null)
                    {
                      //vp.setCurrentItem(position,true);
                      vp.setCurrentItem(vp.getAdapter().getCount()-1,true);
                    }
                  }
            }
            if (position == 1) {
               LoyaltyCardFragment loyaltyCardFragment = getLoyaltyCardFragment();
                if (loyaltyCardFragment != null) {
                   VerticalViewpager vp = loyaltyCardFragment.mypager;
                    if(vp!=null)
                    {
                        vp.setCurrentItem(position);
                    }
                  }
            }
        }
    });
}

@Override
public void onTabUnselected(TabLayout.Tab tab) {
 //This will be called 1st when you select a tab or swipe using viewpager
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
  //This will be called only when you select the already selected tab(Ex: selecting 3rd tab again and again)
}
 private PaymentCardFragment getLoyaltyCardFragment() {
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());

   if(f instanceof PaymentCardFragment)
   {
    return (PaymentCardFragment) f;
   }
   return null;
 }
private LoyaltyCardFragment getPaymentCardFragment() {
    Fragment f = adapter.mFragmentList.get(viewPager.getCurrentItem());
    if(f instanceof LoyaltyCardFragment)
   {
    return (LoyaltyCardFragment) f;
   }
   return null;
 }
  class ViewPagerAdapter extends FragmentPagerAdapter {
   public List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();
   public void addFragment(Fragment fragment, String title) {
   mFragmentList.add(fragment);
   mFragmentTitleList.add(title);
  }
 }
}
anand krish
fuente
1

Esto también puede ayudar

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int i, float v, int i1) {
    }

    @Override
    public void onPageSelected(int i) {
        tablayout.getTabAt(i).select();
    }

    @Override
    public void onPageScrollStateChanged(int i) {
    }
});
Hadi Note
fuente
1

Si resulta que su pestaña predeterminada es la primera (0) y cambia a un fragmento, debe reemplazar el fragmento manualmente por primera vez. Esto se debe a que la pestaña se selecciona antes de que el oyente se registre.

private TabLayout mTabLayout;

...

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_tablayout, container, false);
    mTabLayout = view.findViewById(R.id.sliding_tabs);
    mTabLayout.addOnTabSelectedListener(mOnTabSelectedListener);

    getActivity().getSupportFragmentManager().beginTransaction()
        .replace(R.id.tabContent, MyFirstFragment.newInstance()).commit();
    return view;
}

Alternativamente, puede considerar llamar getTabAt(0).select()y anular onTabReselectedasí:

@Override
public void onTabReselected(TabLayout.Tab tab) {
    // Replace the corresponding tab fragment.
}

Esto funcionaría porque esencialmente está reemplazando el fragmento en cada pestaña nuevamente seleccionada.

farthVader
fuente
0

Puede establecer la posición de TabLayout utilizando las siguientes funciones

public void setTab(){
 tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true);
 tabLayout.setSelected(true);
}
Dhruv Narayan Singh
fuente
0

Si tiene problemas para comprender, este código puede ayudarlo

private void MyTabLayout(){
    TabLayout.Tab myTab = myTabLayout.newTab(); // create a new tab
    myTabLayout.addTab(myTab); // add my new tab to myTabLayout
    myTab.setText("new tab"); 
    myTab.select(); // select the new tab
}

También puede agregar esto a su código:

myTabLayout.setTabTextColors(getColor(R.color.colorNormalTab),getColor(R.color.colorSelectedTab));
M3TALzero1
fuente
0

Intenta de esta manera.

tabLayout.setTabTextColors(getResources().getColor(R.color.colorHintTextLight),
                           getResources().getColor(R.color.colorPrimaryTextLight));
Anandharaj R
fuente
0

si está usando TabLayout sin viewPager, esto ayuda

 mTitles = getResources().getStringArray(R.array.tabItems);
    mIcons = getResources().obtainTypedArray(R.array.tabIcons);
    for (int i = 0; i < mTitles.length; i++) {

        tabs.addTab(tabs.newTab().setText(mTitles[i]).setIcon(mIcons.getDrawable(i)));
        if (i == 0) {
            /*For setting selected position 0 at start*/
            Objects.requireNonNull(Objects.requireNonNull(tabs.getTabAt(i)).getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
        }
    }

    tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary), PorterDuff.Mode.SRC_IN);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            Objects.requireNonNull(tab.getIcon()).setColorFilter(ContextCompat.getColor(getApplicationContext(), R.color.white), PorterDuff.Mode.SRC_IN);
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });
Tijo Thomas
fuente
0

Kotlin Fix

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)

Juan Ocampo
fuente
0
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));

esto seleccionará la pestaña como ver la página de deslizamiento del localizador

Rachit Vohera
fuente