Selezione scheda TabLayout


Risposte:


418

Se conosci l'indice della scheda che desideri selezionare, puoi farlo in questo modo:

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

Questa tecnica funziona anche se stai usando TabLayout da solo senza un ViewPager (che è atipico e probabilmente una cattiva pratica, ma l'ho visto fatto).


10
Questa soluzione funziona solo se la scheda è stata aggiunta alla barra delle azioni, il che potrebbe non essere sempre il caso. Dalla documentazione per TabLayout.Tab.select(): "Seleziona questa scheda. Valido solo se la scheda è stata aggiunta alla barra delle azioni."
Daniel Kvist,

7
@DanielKvist, in realtà la documentazione stessa non è corretta. Il codice sorgente parla da solo. Questa risposta dovrebbe essere la risposta accettata.
Jason Sparc,

@JasonSparc Hmm, ricordo che non ha funzionato per me l'ultima volta che ho provato questa soluzione, ma vedrò se posso controllare due volte come funziona per me. Hai provato? Potrebbe funzionare in alcuni casi, mentre non in altri casi? Potrebbe dipendere dal livello API o qualcosa di simile?
Daniel Kvist,

Grazie per aver eliminato l'Aria su risposte a metà cottura! Perché questo non funziona su TabLayout autonomo probabilmente a causa del motivo che hai dichiarato; È pensato per funzionare con le schede in Actionbar!
sud007,

3
Perché usare TabLayout senza ViewPager dovrebbe essere considerato una cattiva pratica?
tomalf2,

85

Ecco come l'ho risolto:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}

3
La risposta selezionata non ha funzionato per me, ma questa ha funzionato.
Rafal Zawadzki,

ottima soluzione! ha funzionato bene per me, quando avevo bisogno di tornare alla prima pagina sia viewPager che TabView
sashk0

49

Usa questo:

tabs.getTabAt(index).select();

grazie, questa è una soluzione sicura per la mia implementazione
islam farid

Objects.requireNonNull(tabs.getTabAt(position)).select();sicuro da usare
Williaan Lopes,

1
Tieni presente che, se currentTabIndex e index sono uguali, questo invia il flusso a onTabReselected e non onTabSelected.
Abhishek Kumar,

@WilliaanLopes, questo non ti proteggerà dall'NPI, lo lancerà prima
Krzysztof Kubicki,

33

Usa questo:

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

Dopo in OnClickListener:

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

cosa succede se tabMode è scorrevole?
GvSharma,

Penso lo stesso, per favore prima provaci.
Pravin Suthar,

23

Questa probabilmente non è la soluzione definitiva , e richiede di usare TabLayoutinsieme aViewPager , ma è così che l'ho risolto:

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

Ho testato l'impatto delle prestazioni dell'utilizzo di questo codice osservando prima i monitor della CPU e della memoria in Android Studio durante l'esecuzione del metodo, quindi confrontandolo con il carico che è stato inserito nella CPU e nella memoria quando ho navigato tra le pagine me stesso (usando i gesti di scorrimento) e la differenza non è significativamente grande, quindi almeno non è una soluzione orribile ...

Spero che questo aiuti qualcuno!


1
Quando ho fatto la soluzione di dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), quando ho fatto clic sulla scheda a destra, non ho aggiornato la pagina di ViewPager (non so perché). Solo facendo clic indietro sulla scheda sinistra e quindi nuovamente sulla scheda destra, si aggiorna infine la pagina per avere la pagina della scheda destra, che è molto glitch. Ma questa soluzione non ha avuto problemi.
Rock Lee,

12

Se non puoi usare tab.select () e non vuoi usare un ViewPager, puoi comunque selezionare una scheda a livello di programmazione. Se stai usando una vista personalizzata attraverso di TabLayout.Tab setCustomView(android.view.View view)essa è più semplice. Ecco come farlo in entrambi i modi.

// 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 non stai utilizzando una vista personalizzata, puoi farlo in questo modo

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

Utilizzare un StateListDrawable per alternare tra disegni estraibili selezionati e non selezionati o qualcosa di simile per fare ciò che si desidera con colori e / o disegni.


12

Basta impostare viewPager.setCurrentItem(index)e il TabLayout associato selezionerebbe la rispettiva scheda.


Questo non ha funzionato per me. Ho dovuto usare il metodo .post.
arenaq,

7

Puoi provare a risolverlo con questo:

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

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

5

prova questo

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

Thanks.it ha funzionato per me. Ma è buona norma utilizzare il ritardo?
Harsh Shah,

Immagino sia male eseguire il thread su una qualsiasi delle cause del layout se supponiamo che stai recuperando il testo per la scheda dal server back-end e se per qualsiasi motivo il server ritarda, questo thread di sistema consumerà in modo non necessario le risorse del tuo dispositivo.
cammando il

soluzione così brutta
Lester,

Questo non funziona per me. Come faccio a farlo se l'utente fa clic su una scheda, quindi ritardare la selezione di tale scheda? Non riesco a far funzionare nulla. Ho provato invece se i == 1 da usare (mViewPager.getCurrentItem () == 0) ma non funziona e non fa nient'altro.
iBEK il

5

Un po 'in ritardo, ma potrebbe essere una soluzione utile. Sto usando il mio TabLayout direttamente nel mio frammento e sto provando a selezionare una scheda abbastanza presto nel ciclo di vita del frammento. Quello che ha funzionato per me è stato aspettare fino a quando TabLayout ha finito di disegnare le sue viste figlio usando il android.view.View#postmetodo. vale a dire:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });

la risposta corretta ha funzionato per me, ma un certo ritardo gli darà un buon effetto new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham,

3

Io sto usando TabLayout per passare frammenti. Funziona per la maggior parte, tranne quando ho provato a selezionare una scheda in modo programmatico usando tab.select(), il mio TabLayout.OnTabSelectedListeneravrebbe innescato il onTabSelected(TabLayout.Tab tab), il che mi avrebbe causato molto dolore. Stavo cercando un modo per fare la selezione programmatica senza innescare l'ascoltatore.

Quindi ho adattato la risposta di @kenodoggy al mio uso. Stavo affrontando ulteriormente un problema in cui alcuni degli oggetti interni sarebbero tornati null (perché non erano ancora stati creati, perché rispondevo onActivityResult()dal mio frammento, che si verifica prima onCreate()nel caso l'attività sia singleTasko singleInstance), quindi ho scritto un dettagliato se / else sequenza che segnalerebbe l'errore e cadrebbe senza NullPointerExceptionche altrimenti si innescherebbe. Uso Timber per la registrazione, se non si utilizza quel sostituto con 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");
    }
}

Qui tabLayout è la mia variabile di memoria associata TabLayoutall'oggetto nel mio XML. E non utilizzo la funzione di scorrimento delle schede, quindi ho rimosso anche quella.


3

dovresti usare un viewPager per usare 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

aggiungi per il tuo 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) {
            }
        });

// sul gestore per impedire il crash outofmemory

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}

1
"prevenire crash outofmemory" - perché abbiamo bisogno di thread separati per selezionare l'elemento corrente?
AppiDevo,

2

Una soluzione combinata con risposte diverse è:

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

  myViewPager.setCurrentItem(position, true);

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


1

Per impostazione predefinita, se si seleziona una scheda, questa verrà evidenziata. Se si desidera selezionare esplicitamente significa utilizzare il codice commentato specificato in onTabSelected (scheda TabLayout.Tab) con la posizione dell'indice della scheda specificata. Questo codice spiega come modificare il frammento nella posizione selezionata sulla scheda usando 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

Anche questo può aiutare

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

In tal caso, la scheda predefinita è la prima (0) e si passa a un frammento, quindi è necessario sostituire manualmente il frammento per la prima volta. Questo perché la scheda è selezionata prima che l'ascoltatore venga registrato.

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

In alternativa, puoi considerare di chiamare getTabAt(0).select()e sovrascrivere in questo onTabReselectedmodo:

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

Questo funzionerebbe perché stai essenzialmente sostituendo il frammento su ogni scheda selezionata nuovamente.


0

È possibile impostare la posizione TabLayout utilizzando le seguenti funzioni

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

0

Se hai difficoltà a capire, questo codice può aiutarti

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
}

Puoi anche aggiungere questo al tuo codice:

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

0

Prova in questo modo.

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

0

se stai usando TabLayout senza viewPager questo aiuta

 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

Correzione di Kotlin

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

questo seleziona la scheda come pagina di scorrimento del pager di visualizzazione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.