Seleção da guia TabLayout

Respostas:

418

Se você conhece o índice da guia que deseja selecionar, pode fazê-lo da seguinte maneira:

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

Essa técnica funciona mesmo se você estiver usando o TabLayout por si só sem um ViewPager (que é uma prática atípica e provavelmente ruim, mas eu já vi isso).

Firefly
fonte
10
Essa solução funciona apenas se a guia tiver sido adicionada à barra de ação, o que pode não ser sempre o caso. Na documentação de TabLayout.Tab.select(): "Selecione esta guia. Válido apenas se a guia tiver sido adicionada à barra de ação."
Daniel Kvist
7
@DanielKvist, na verdade a documentação em si está incorreta. O código fonte fala por si. Esta resposta deve ser a resposta aceita.
Jason Sparc
@ JasonSparc Hmm, lembro que não funcionou para mim na última vez que tentei esta solução, mas vou ver se consigo verificar novamente como funciona para mim. Você tentou? Pode funcionar em alguns casos, enquanto não em outros casos? Pode depender do nível da API ou algo semelhante?
Daniel Kvist
Obrigado por limpar o ar com respostas meio cozidas! Porque isso simplesmente não funciona no TabLayout independente, provavelmente pelo motivo que você declarou; Ele deve funcionar com guias na Actionbar!
sud007
3
Por que usar o TabLayout sem o ViewPager deve ser considerado uma má prática?
tomalf2
85

Foi assim que eu resolvi:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}
dap
fonte
3
A resposta selecionada não funcionou para mim, mas esta funcionou.
Rafal Zawadzki
ótima solução! funcionou bem para mim, quando eu precisava para voltar para a primeira página, tanto viewPager e TabView
sashk0
49

Usa isto:

tabs.getTabAt(index).select();
Riyas PK
fonte
obrigado, esta é uma solução segura quanto à minha implementação
islam farid
Objects.requireNonNull(tabs.getTabAt(position)).select();seguro
Williaan Lopes
1
Lembre-se de que, se currentTabIndex e index forem iguais, isso enviará seu fluxo para onTabReselected e não onTabSelected.
Abhishek Kumar
@WilliaanLopes, isso não vai protegê-lo de NPI, vai simplesmente jogá-lo mais cedo
Krzysztof Kubicki
33

Usa isto:

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

Depois no OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Pravin Suthar
fonte
e se o tabMode for rolável?
GvSharma
Eu penso o mesmo, por favor, primeiro você tenta isso.
Pravin Suthar
23

Provavelmente, essa não é a solução definitiva e requer que você use a TabLayoutjunto com aViewPager , mas foi assim que eu a resolvi:

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

Testei o tamanho do impacto no desempenho do uso desse código, observando primeiro os monitores de CPU e memória no Android Studio enquanto executava o método, depois comparando-o com a carga que foi colocada na CPU e na memória quando navegava pelas páginas eu (usando gestos de furto), e a diferença não é significativamente grande, então pelo menos não é uma solução horrível ...

Espero que isso ajude alguém!

Daniel Kvist
fonte
1
Quando fiz a solução dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), quando cliquei na guia à direita, ela não atualizou a página do ViewPager (não sei por que). Se você clicar novamente na guia esquerda e depois na guia direita novamente, finalmente atualizará a página para ter a página da guia direita, o que é muito complicado. Mas essa solução não teve falhas.
Rock Lee
12

Se você não pode usar tab.select () e não deseja usar um ViewPager, ainda pode selecionar uma guia por meio de programação. Se você estiver usando uma exibição personalizada TabLayout.Tab setCustomView(android.view.View view), é mais simples. Veja como fazer isso nos dois 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
}

Se você não estiver usando uma exibição personalizada, poderá fazê-lo assim

// 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 um StateListDrawable para alternar entre drawables selecionados e não selecionados ou algo semelhante para fazer o que você quer com cores e / ou drawables.

kenodoggy
fonte
12

Basta definir viewPager.setCurrentItem(index)e o TabLayout associado selecionaria a guia respectiva.

Panduka DeSilva
fonte
Isto não funcionou para mim. Eu tive que usar o método .post.
arenaq
7

Você pode tentar resolvê-lo com isso:

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

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

tente isso

    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
fonte
Obrigado. Funcionou para mim. Mas é uma boa prática usar adiado?
Harsh Shah
Eu acho que é ruim executar o thread em qualquer um dos layouts, porque se você está buscando o texto da guia no servidor back-end e se por algum motivo o servidor atrasar, esse thread do sistema consumirá os recursos do seu dispositivo de forma inconsecável.
cammando
solução tão feio
Lester
Isso não funciona para mim. Como faço para que, se o usuário clicar em uma guia, adie a seleção dessa guia? Não consigo fazer nada funcionar. Tentei em vez disso, se eu == 1 para usar (mViewPager.getCurrentItem () == 0), mas não funciona e nem mais nada.
iBEK
5

Um pouco tarde, mas pode ser uma solução útil. Estou usando meu TabLayout diretamente no meu fragmento e tentando selecionar uma guia bem cedo no ciclo de vida do fragmento. O que funcionou para mim foi esperar até que o TabLayout terminasse de desenhar suas visualizações filho usando o android.view.View#postmétodo ou seja:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
ahmed_khan_89
fonte
resposta correta trabalhou para mim, mas algum atraso vai dar bom efeito new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham
3

Eu estou usando TabLayout para mudar fragmentos. Ele funciona na maior parte do tempo, exceto quando eu tentava selecionar uma guia usando programaticamente tab.select(), o meu TabLayout.OnTabSelectedListeneracionava o onTabSelected(TabLayout.Tab tab), o que me causava muita dor. Eu estava procurando uma maneira de fazer a seleção programática sem acionar o ouvinte.

Então adaptei a resposta de @kenodoggy ao meu uso. Eu ainda estava enfrentando um problema em que alguns dos objetos internos retornariam nulos (porque ainda não foram criados, porque eu estava respondendo onActivityResult()do meu fragmento, o que ocorre antes onCreate()no caso em que a atividade é singleTaskou singleInstance) e, por isso, escrevi um / else sequência que informaria o erro e falharia sem a NullPointerExceptionque seria acionada. Eu uso a madeira para registrar, se você não estiver usando esse substituto com 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");
    }
}

Aqui, tabLayout é a minha variável de memória vinculada ao TabLayoutobjeto no meu XML. E como não uso o recurso da guia de rolagem, removi-o também.

Dhiraj Gupta
fonte
3

você deve usar um viewPager para usar o 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
fonte
2

adicione para o seu viewpager:

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

// no manipulador para evitar falhas de memória

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}
Alex Zaraos
fonte
1
"impedir falha de memória" - por que precisamos de um segmento separado para selecionar o item atual?
AppiDevo
2

Uma solução combinada de respostas diferentes é:

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

  myViewPager.setCurrentItem(position, true);

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

Com o TabLayoutfornecido pela Biblioteca de componentes de materiais, basta usar o selectTabmétodo:

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

insira a descrição da imagem aqui

Requer a versão 1.1.0.

Gabriele Mariotti
fonte
Não, selectTab é um método privado de pacote.
XY
@ xyuber.com Adicionei uma informação importante. Requer a versão 1.1.0. O método é público agora
Gabriele Mariotti
1

Por padrão, se você selecionar uma guia, ela será destacada. Se você deseja selecionar Explicitamente, use o código comentado fornecido em onTabSelected (guia TabLayout.Tab) com a posição do índice da guia especificada. Este código explica como alterar o fragmento na posição selecionada na guia usando o 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
fonte
1

Isso também pode ajudar

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
fonte
1

Se a sua guia padrão for a primeira (0) e você mudar para um fragmento, substitua-o manualmente pela primeira vez. Isso ocorre porque a guia é selecionada antes que o ouvinte seja registrado.

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

Como alternativa, você pode considerar chamar getTabAt(0).select()e substituir da seguinte onTabReselectedmaneira:

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

Isso funcionaria porque você está substituindo essencialmente o fragmento em todas as guias selecionadas novamente.

farthVader
fonte
0

Você pode definir a posição TabLayout usando as seguintes funções

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

Se você tiver problemas para entender, esse código pode ajudá-lo

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
}

Você também pode adicionar isso ao seu código:

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

Tente assim.

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

se você estiver usando o TabLayout sem o viewPager, isso ajudará

 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
fonte
0

Kotlin fix

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)

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

isso selecionará a guia como visualizar a página de furto do pager

Rachit Vohera
fonte