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).


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

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();

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();

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!


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.


12

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


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

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

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

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.


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

            }
        });

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

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


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

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

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.


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

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

0

Tente assim.

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

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

        }
    });

0

Kotlin fix

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.