Wybór zakładki TabLayout

Odpowiedzi:

418

Jeśli znasz indeks karty, którą chcesz wybrać, możesz to zrobić w następujący sposób:

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

Ta technika działa nawet wtedy, gdy używasz TabLayout samodzielnie bez ViewPager (co jest nietypowe i prawdopodobnie złe praktyki, ale widziałem, że to zrobione).

Robaczek świętojański
źródło
10
To rozwiązanie działa tylko wtedy, gdy karta została dodana do paska akcji, co może nie zawsze mieć miejsce. Z dokumentacji dla TabLayout.Tab.select(): „Wybierz tę kartę. Ważne tylko, jeśli karta została dodana do paska akcji”.
Daniel Kvist
7
@DanielKvist, sama dokumentacja jest niepoprawna. Kod źródłowy mówi sam za siebie. Ta odpowiedź powinna być odpowiedzią zaakceptowaną.
Jason Sparc
@JasonSparc Hmm, pamiętam, że nie działało dla mnie, kiedy ostatnio wypróbowałem to rozwiązanie, ale zobaczę, czy mogę sprawdzić dwukrotnie, jak to działa dla mnie. Czy próbowałeś? W niektórych przypadkach może działać, a nie w innych? Może to zależeć od poziomu interfejsu API lub czegoś podobnego?
Daniel Kvist
Dzięki za wyczyszczenie Air na pół gotowane odpowiedzi! Ponieważ to po prostu nie działa na samodzielnym TabLayout prawdopodobnie z powodu podanego powodu; Ma działać z kartami na pasku akcji!
sud007
3
Dlaczego używanie TabLayout bez ViewPager powinno być uważane za złą praktykę?
tomalf2
85

Oto jak to rozwiązałem:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}
dap
źródło
3
Wybrana odpowiedź nie działała dla mnie, ale ta zadziałała.
Rafał Zawadzki
świetne rozwiązanie! działało dobrze dla mnie, gdy musiałem wrócić do pierwszej strony zarówno viewPager, jak i TabView
sashk0
49

Użyj tego:

tabs.getTabAt(index).select();
Riyas PK
źródło
dzięki, to bezpieczne rozwiązanie jak na moje wdrożenie
islam farid
Objects.requireNonNull(tabs.getTabAt(position)).select();bezpieczny w użyciu
Williaan Lopes,
1
Należy pamiętać, że jeśli currentTabIndex i indeks są takie same, to przesyła przepływ do onTabReselected, a nie onTabSelected.
Abhishek Kumar,
@WilliaanLopes, to nie ochroni cię przed NPI, po prostu rzuci go wcześniej
Krzysztof Kubicki
33

Użyj tego:

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

Po w OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Pravin Suthar
źródło
co jeśli tabMode można przewijać?
GvSharma
Myślę tak samo, najpierw spróbuj tego.
Pravin Suthar
23

Prawdopodobnie nie jest to najlepsze rozwiązanie i wymaga użycia TabLayoutrazem zViewPager , ale tak to rozwiązałem:

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

Testowałem, jak duży wpływ na wydajność ma użycie tego kodu, najpierw patrząc na monitory procesora i pamięci w Android Studio podczas uruchamiania metody, a następnie porównując go z obciążeniem procesora i pamięci podczas nawigacji między stronami ja (używając gestów machnięcia), a różnica nie jest znacząco duża, więc przynajmniej nie jest to okropne rozwiązanie ...

Mam nadzieję, że to komuś pomoże!

Daniel Kvist
źródło
1
Kiedy zrobiłem dap's solution ( tabLayout.setScrollPosition(pageIndex,0f,true);), kiedy kliknąłem kartę po prawej stronie, nie zaktualizowałem strony ViewPager (nie wiem dlaczego). Tylko ponowne kliknięcie lewej karty, a następnie ponownie prawej karty, w końcu zaktualizuje stronę, tak aby strona prawej karty była bardzo błędna. Ale to rozwiązanie nie miało żadnych problemów.
Rock Lee
12

Jeśli nie możesz użyć tab.select () i nie chcesz używać ViewPager, nadal możesz programowo wybrać kartę. Jeśli korzystasz z niestandardowego widoku, TabLayout.Tab setCustomView(android.view.View view)jest to prostsze. Oto jak to zrobić na dwa sposoby.

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

Jeśli nie używasz widoku niestandardowego, możesz to zrobić w ten sposób

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

Użyj StateListDrawable, aby przełączać między wybranymi i niezaznaczonymi rysunkami lub coś podobnego, aby robić to, co chcesz z kolorami i / lub rysunkami.

kenodoggy
źródło
12

Po prostu ustaw viewPager.setCurrentItem(index)i powiązany TabLayout wybierze odpowiednią kartę.

Panduka DeSilva
źródło
To nie działało dla mnie. Musiałem użyć metody .post.
arenaq
7

Możesz spróbować rozwiązać to w ten sposób:

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

TabLayout.Tab tab = tabLayout.getTabAt(pos);
if (tab != null) {
    tab.select();
}
CoCo Dev
źródło
5

Spróbuj tego

    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
źródło
Dzięki. Działało dla mnie. Ale czy warto używać opóźnionego?
Harsh Shah
Wydaje mi się, że źle jest uruchamiać wątek na dowolnym układzie, ponieważ jeśli założysz, że pobierasz tekst tabu z serwera zaplecza, a jeśli z jakiegoś powodu serwer opóźni się, ten wątek systemowy niepotrzebnie zużyje zasoby twojego urządzenia.
cammando
takie brzydkie rozwiązanie
Lester
To mi nie działa. Jak sprawić, żeby kliknięcie karty przez użytkownika opóźniało jej wybór? Nie mogę zmusić niczego do pracy. Próbowałem zamiast tego, jeśli i == 1 użyć (mViewPager.getCurrentItem () == 0), ale to nie działa i nie robi nic innego.
iBEK,
5

Trochę za późno, ale może być przydatnym rozwiązaniem. Korzystam z TabLayout bezpośrednio w moim fragmencie i staram się wybrać kartę dość wcześnie w cyklu życia fragmentu. To, co działało dla mnie, to czekać, aż TabLayout zakończy rysowanie widoków potomnych przy użyciu android.view.View#postmetody. to znaczy:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
ahmed_khan_89
źródło
poprawna odpowiedź zadziałała dla mnie, ale pewne opóźnienie da jej dobry efekt new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham
3

Ja jestem za pomocą TabLayout przełączyć fragmenty. Działa w przeważającej części, z wyjątkiem przypadków, gdy próbowałem programowo wybrać kartę za pomocą tab.select(), mój TabLayout.OnTabSelectedListenerwyzwalałby onTabSelected(TabLayout.Tab tab), co wywołałoby u mnie wielki smutek. Szukałem sposobu na dokonanie wyboru programowego bez uruchamiania odbiornika.

Dostosowałem więc odpowiedź @kenodoggy do mojego zastosowania. Miałem też problem z tym, że niektóre wewnętrzne obiekty zwróciłyby wartość null (ponieważ nie zostały jeszcze utworzone, ponieważ odpowiadałem onActivityResult()z mojego fragmentu, co występuje wcześniej onCreate()w przypadku, gdy działanie jest singleTasklub singleInstance), więc napisałem szczegółowe, jeśli / else sekwencja, która zgłosi błąd i przejdzie bez tego NullPointerException, co w przeciwnym razie uruchomiłoby się. Używam Timber do logowania, jeśli nie używasz tego zamiennika z 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");
    }
}

TabLayout jest tutaj moją zmienną pamięci związaną z TabLayoutobiektem w moim pliku XML. I nie używam funkcji przewijania, więc też ją usunąłem.

Dhiraj Gupta
źródło
3

powinieneś użyć viewPager, aby użyć 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
źródło
2

dodaj do przeglądarki:

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

// na module obsługi, aby zapobiec awarii pamięci

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}
Alex Zaraos
źródło
1
„zapobiegaj awarii pamięci” - dlaczego potrzebujemy osobnego wątku, aby wybrać bieżący element?
AppiDevo,
2

Połączone rozwiązanie z różnych odpowiedzi to:

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

  myViewPager.setCurrentItem(position, true);

  myTabLayout.setScrollPosition(position, 0f, true);
},
100);
Strefa
źródło
2

Z TabLayoutdostarczonej przez bibliotekę komponentów materiałów wystarczy użyć selectTabmetody:

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

wprowadź opis zdjęcia tutaj

Wymaga wersji 1.1.0.

Gabriele Mariotti
źródło
Nie, selectTab to metoda prywatna dla pakietu.
XY
@ xyuber.com Dodałem ważną informację. Wymaga wersji 1.1.0. Metoda jest teraz publiczna
Gabriele Mariotti
1

Domyślnie, jeśli wybierzesz kartę, zostanie ona podświetlona. Jeśli chcesz wybrać Jawnie, oznacza to, że użyj podanego w komentarzu kodu w polu onTabSelected (tabLayout.Tab) z określoną pozycją indeksu tabulatorów. Ten kod objaśnia zmiany fragmentu na wybranej pozycji zakładki za pomocą przeglądarki.

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
źródło
1

To też może pomóc

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) {
    }
});
Uwaga Hadi
źródło
1

Jeśli tak się stanie, że domyślna karta jest pierwsza (0) i zdarzy się, że przełączysz się na fragment, musisz ręcznie zastąpić fragment po raz pierwszy. Jest tak, ponieważ karta jest wybierana przed zarejestrowaniem się nasłuchiwacza.

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

Alternatywnie możesz rozważyć wywołanie getTabAt(0).select()i zastąpienie w następujący onTabReselectedsposób:

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

To działałoby, ponieważ zasadniczo zamieniasz fragment przy każdej ponownej selekcji karty.

farthVader
źródło
0

Możesz ustawić pozycję TabLayout za pomocą następujących funkcji

public void setTab(){
 tabLayout.setScrollPosition(YOUR_SCROLL_INDEX,0,true);
 tabLayout.setSelected(true);
}
Dhruv Narayan Singh
źródło
0

Jeśli masz problemy ze zrozumieniem, ten kod może ci pomóc

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
}

Możesz również dodać to do swojego kodu:

myTabLayout.setTabTextColors(getColor(R.color.colorNormalTab),getColor(R.color.colorSelectedTab));
M3TALzero1
źródło
0

Wypróbuj w ten sposób

tabLayout.setTabTextColors(getResources().getColor(R.color.colorHintTextLight),
                           getResources().getColor(R.color.colorPrimaryTextLight));
Anandharaj R.
źródło
0

jeśli używasz TabLayout bez viewPager, to pomaga

 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
źródło
0

Poprawka Kotlin

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)

Juan Ocampo
źródło
0
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));

spowoduje to wybranie zakładki jako strony przesuwania strony pager

Rachit Vohera
źródło