Sélection de l'onglet TabLayout

Réponses:

418

Si vous connaissez l'index de l'onglet que vous souhaitez sélectionner, vous pouvez le faire comme suit:

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

Cette technique fonctionne même si vous utilisez TabLayout seul sans ViewPager (ce qui est atypique et probablement une mauvaise pratique, mais je l'ai vu faire).

Luciole
la source
10
Cette solution ne fonctionne que si l'onglet a été ajouté à la barre d'actions, ce qui n'est pas toujours le cas. Dans la documentation de TabLayout.Tab.select(): "Sélectionnez cet onglet. Valide uniquement si l'onglet a été ajouté à la barre d'actions."
Daniel Kvist du
7
@DanielKvist, en fait la documentation elle-même est incorrecte. Le code source parle de lui-même. Cette réponse doit être la réponse acceptée.
Jason Sparc
@JasonSparc Hmm, je me souviens que cela ne fonctionnait pas pour moi la dernière fois que j'ai essayé cette solution, mais je vais voir si je peux vérifier à nouveau comment cela fonctionne pour moi. As-tu essayé? Cela pourrait fonctionner dans certains cas, mais pas dans d'autres cas? Cela peut dépendre du niveau API ou quelque chose de similaire?
Daniel Kvist
Merci d'avoir nettoyé l'air des réponses à moitié cuites! Parce que cela ne fonctionne tout simplement pas sur TabLayout autonome, probablement pour la raison que vous avez indiquée; Il est censé fonctionner avec des onglets dans la barre d'action!
sud007
3
Pourquoi utiliser TabLayout sans ViewPager devrait être considéré comme une mauvaise pratique?
tomalf2
85

Voici comment je l'ai résolu:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}
dap
la source
3
La réponse sélectionnée n'a pas fonctionné pour moi, mais celle-ci a fonctionné.
Rafal Zawadzki
bonne solution! a bien fonctionné pour moi, quand je devais revenir à la première page viewPager et TabView
sashk0
49

Utilisez ceci:

tabs.getTabAt(index).select();
Riyas PK
la source
merci, c'est une solution sûre pour mon implémentation
islam farid
Objects.requireNonNull(tabs.getTabAt(position)).select();sûr à utiliser
Williaan Lopes
1
Gardez à l'esprit que si currentTabIndex et index sont identiques, cela envoie votre flux à onTabReselected et non à onTabSelected.
Abhishek Kumar
@WilliaanLopes, cela ne vous protégera pas du NPI, le lancera plus tôt
Krzysztof Kubicki
33

Utilisez ceci:

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

Après dans OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Pravin Suthar
la source
que faire si le tabMode est défilable?
GvSharma
Je pense la même chose, veuillez d'abord essayer.
Pravin Suthar
23

Ce n'est probablement pas la solution ultime , et cela nécessite que vous utilisiez le TabLayoutavec unViewPager , mais voici comment je l'ai résolu:

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

J'ai testé l'ampleur de l'impact sur les performances de l'utilisation de ce code en examinant d'abord les moniteurs de CPU et de mémoire dans Android Studio lors de l'exécution de la méthode, puis en les comparant à la charge qui a été placée sur le CPU et la mémoire lorsque j'ai navigué entre les pages. moi-même (en utilisant des gestes de balayage), et la différence n'est pas significativement grande, donc au moins ce n'est pas une solution horrible ...

J'espère que cela aide quelqu'un!

Daniel Kvist
la source
1
Quand j'ai fait la solution de dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), quand j'ai cliqué sur l'onglet à droite, cela n'a pas mis à jour la page de ViewPager (je ne sais pas pourquoi). Un simple clic sur l'onglet de gauche puis sur l'onglet de droite mettrait enfin à jour la page pour avoir la page de l'onglet de droite, ce qui est très glitch. Mais cette solution n'a eu aucun problème.
Rock Lee
12

Si vous ne pouvez pas utiliser tab.select () et que vous ne souhaitez pas utiliser un ViewPager, vous pouvez toujours sélectionner un onglet par programme. Si vous utilisez une vue personnalisée, TabLayout.Tab setCustomView(android.view.View view)c'est plus simple. Voici comment procéder dans les deux sens.

// 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 vous n'utilisez pas une vue personnalisée, vous pouvez le faire comme ceci

// 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
}

Utilisez un StateListDrawable pour basculer entre les dessinables sélectionnés et non sélectionnés ou quelque chose de similaire pour faire ce que vous voulez avec les couleurs et / ou les dessinables.

kenodoggy
la source
12

Il suffit de définir viewPager.setCurrentItem(index)et le TabLayout associé sélectionnerait l'onglet respectif.

Panduka DeSilva
la source
Cela n'a pas fonctionné pour moi. J'ai dû utiliser la méthode .post.
arenaq
7

Vous pouvez essayer de le résoudre avec ceci:

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

TabLayout.Tab tab = tabLayout.getTabAt(pos);
if (tab != null) {
    tab.select();
}
CoCo Dev
la source
6

Un peu en retard mais pourrait être une solution utile. J'utilise ma TabLayout directement dans mon fragment et j'essaie de sélectionner un onglet assez tôt dans le cycle de vie du fragment. Ce qui a fonctionné pour moi, c'est d'attendre que TabLayout ait fini de dessiner ses vues enfant en utilisant la android.view.View#postméthode. c'est à dire:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
ahmed_khan_89
la source
la bonne réponse a fonctionné pour moi mais un certain retard lui donnera un bel effet new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham
5

essaye ça

    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
la source
Merci, ça a marché pour moi. Mais est-ce une bonne pratique d'utiliser retardé?
Harsh Shah
Je suppose qu'il est mauvais d'exécuter le thread sur l'une des causes de la mise en page si vous supposez que vous récupérez le texte de l'onglet sur le serveur principal et que si une raison quelconque retarde le serveur, ce thread système consommera inutilement les ressources de votre appareil.
cammando
solution si laide
Lester
Ça ne marche pas pour moi. Comment puis-je faire en sorte que si l'utilisateur clique sur un onglet, puis retarder cette sélection d'onglet? Je ne peux rien faire travailler. J'ai plutôt essayé d'utiliser i == 1 (mViewPager.getCurrentItem () == 0) mais cela ne fonctionne pas et rien d'autre.
iBEK
3

Je suis utilise TabLayout pour passer des fragments. Cela fonctionne pour la plupart, sauf lorsque j'essaie de sélectionner un onglet par programmation tab.select(), mon TabLayout.OnTabSelectedListenerdéclenche laonTabSelected(TabLayout.Tab tab) , ce qui me causerait beaucoup de chagrin. Je cherchais un moyen de faire une sélection programmatique sans déclencher l'auditeur.

J'ai donc adapté la réponse de @kenodoggy à mon utilisation. J'étais en outre confronté à un problème où certains des objets internes retourneraient nuls (car ils n'étaient pas encore créés, parce que je répondais à onActivityResult()partir de mon fragment, ce qui se produit avant onCreate()dans le cas où l'activité est singleTaskou singleInstance) alors j'ai rédigé un détail si / else séquence qui signalerait l'erreur et NullPointerExceptionpasserait sans que cela ne se déclenche autrement. J'utilise Timber pour la journalisation, si vous n'utilisez pas ce substitut avec 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");
    }
}

Ici, tabLayout est ma variable de mémoire liée à l' TabLayoutobjet dans mon XML. Et je n'utilise pas la fonction d'onglet de défilement, j'ai donc supprimé cela également.

Dhiraj Gupta
la source
3

vous devez utiliser un viewPager pour utiliser 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
la source
2

ajouter pour votre viseur:

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

// sur le gestionnaire pour éviter les pannes hors de la mémoire

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}
Alex Zaraos
la source
1
"empêcher le crash hors mémoire" - pourquoi avons-nous besoin d'un thread séparé pour sélectionner l'élément en cours?
AppiDevo
2

Une solution combinée à partir de différentes réponses est:

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

  myViewPager.setCurrentItem(position, true);

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

Avec le TabLayoutfourni par la bibliothèque de composants de matériaux utilisez simplement la selectTabméthode:

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

entrez la description de l'image ici

Il nécessite la version 1.1.0.

Gabriele Mariotti
la source
Non, selectTab est une méthode de package privé.
XY
@ xyuber.com J'ai ajouté une information importante. Il nécessite la version 1.1.0. La méthode est maintenant publique
Gabriele Mariotti
1

Par défaut, si vous sélectionnez un onglet, il sera mis en surbrillance. Si vous souhaitez sélectionner Explicitement signifie utiliser le code commenté donné sous onTabSelected (onglet TabLayout.Tab) avec votre position d'index d'onglet spécifiée. Ce code explique le changement de fragment sur la position sélectionnée de l'onglet à l'aide du viewpager.

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
la source
1

Cela peut aussi aider

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
la source
1

S'il se trouve que votre onglet par défaut est le premier (0) et que vous passez à un fragment, vous devez remplacer manuellement le fragment pour la première fois. En effet, l'onglet est sélectionné avant que l'auditeur ne soit enregistré.

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

Alternativement, vous pouvez envisager d'appeler getTabAt(0).select()et de remplacer onTabReselectedcomme ceci:

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

Cela fonctionnerait car vous remplacez essentiellement le fragment à chaque nouvelle sélection d'onglet.

farthVader
la source
0

Vous pouvez définir la position de TabLayout à l'aide des fonctions suivantes

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

Si vous avez du mal à comprendre, ce code peut vous aider

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
}

Vous pouvez également ajouter ceci à votre code:

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

Essayez de cette façon.

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

si vous utilisez TabLayout sans viewPager cela aide

 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
la source
0

Correction de Kotlin

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)

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

cela sélectionnera l'onglet comme page de balayage du téléavertisseur

Rachit Vohera
la source