TabLayout-Tab-Auswahl

Antworten:

418

Wenn Sie den Index der Registerkarte kennen, die Sie auswählen möchten, können Sie dies folgendermaßen tun:

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

Diese Technik funktioniert auch dann, wenn Sie das TabLayout alleine ohne ViewPager verwenden (was untypisch ist und wahrscheinlich eine schlechte Praxis ist, aber ich habe es gesehen).

Firefly
quelle
10
Diese Lösung funktioniert nur, wenn die Registerkarte zur Aktionsleiste hinzugefügt wurde, was möglicherweise nicht immer der Fall ist. Aus der Dokumentation für TabLayout.Tab.select(): "Wählen Sie diese Registerkarte. Nur gültig, wenn die Registerkarte zur Aktionsleiste hinzugefügt wurde."
Daniel Kvist
7
@ DanielKvist, eigentlich ist die Dokumentation selbst falsch. Der Quellcode spricht für sich. Diese Antwort sollte die akzeptierte Antwort sein.
Jason Sparc
@JasonSparc Hmm, ich erinnere mich, dass es bei mir nicht funktioniert hat, als ich diese Lösung das letzte Mal ausprobiert habe, aber ich werde sehen, ob ich überprüfen kann, wie es bei mir funktioniert. Hast du es versucht? Es könnte in einigen Fällen funktionieren, in anderen Fällen nicht? Es könnte von der API-Ebene oder etwas Ähnlichem abhängen?
Daniel Kvist
Vielen Dank, dass Sie die Luft für halb gekochte Antworten geklärt haben! Weil das auf eigenständigem TabLayout wahrscheinlich aus dem von Ihnen angegebenen Grund einfach nicht funktioniert; Es soll mit Tabs in der Actionbar funktionieren!
Sud007
3
Warum sollte die Verwendung von TabLayout ohne ViewPager als schlechte Praxis angesehen werden?
Tomalf2
84

So habe ich es gelöst:

void selectPage(int pageIndex){
    tabLayout.setScrollPosition(pageIndex,0f,true);
    viewPager.setCurrentItem(pageIndex);
}
dap
quelle
3
Die ausgewählte Antwort hat bei mir nicht funktioniert, aber diese hat funktioniert.
Rafal Zawadzki
tolle Lösung! funktionierte gut für mich, als ich zur ersten Seite zurückkehren musste, sowohl viewPager als auch TabView
sashk0
49

Benutze das:

tabs.getTabAt(index).select();
Riyas PK
quelle
danke, dies ist eine sichere lösung für meine umsetzung
islam farid
Objects.requireNonNull(tabs.getTabAt(position)).select();sicher zu bedienen
Williaan Lopes
1
Beachten Sie, dass, wenn currentTabIndex und index identisch sind, Ihr Flow an onTabReselected und nicht an onTabSelected gesendet wird.
Abhishek Kumar
@ WilliaanLopes, dies wird Sie nicht vor NPI schützen, wird es nur früher werfen
Krzysztof Kubicki
33

Benutze das:

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

Nach in OnClickListener:

TabLayout tabLayout = (TabLayout) findViewById(R.id.patienthomescreen_tabs);
TabLayout.Tab tab = tabLayout.getTabAt(someIndex);
tab.select();
Pravin Suthar
quelle
Was ist, wenn der tabMode scrollbar ist?
GvSharma
Ich denke das gleiche, bitte versuchen Sie es zuerst.
Pravin Suthar
23

Dies ist wahrscheinlich nicht die ultimative Lösung , und es erfordert, dass Sie die TabLayoutzusammen mit a verwendenViewPager , aber so habe ich es gelöst:

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

Ich habe getestet, wie groß die Auswirkungen der Verwendung dieses Codes auf die Leistung sind, indem ich zuerst die CPU- und Speichermonitore in Android Studio betrachtete, während ich die Methode ausführte, und sie dann mit der Last verglich, die der CPU und dem Speicher beim Navigieren zwischen den Seiten auferlegt wurde Ich selbst (mit Wischgesten), und der Unterschied ist nicht wesentlich, also ist es zumindest keine schreckliche Lösung ...

Hoffe das hilft jemandem!

Daniel Kvist
quelle
1
Als ich die Lösung von dap ( tabLayout.setScrollPosition(pageIndex,0f,true);) ausgeführt habe und auf die Registerkarte rechts geklickt habe, wurde die Seite des ViewPager nicht aktualisiert (ich weiß nicht warum). Wenn Sie nur auf die linke Registerkarte und dann wieder auf die rechte Registerkarte klicken, wird die Seite endgültig aktualisiert, sodass die Seite der rechten Registerkarte angezeigt wird, was sehr problematisch ist. Aber diese Lösung hatte keine Störungen.
Rock Lee
12

Wenn Sie tab.select () nicht verwenden können und keinen ViewPager verwenden möchten, können Sie dennoch programmgesteuert eine Registerkarte auswählen. Wenn Sie eine benutzerdefinierte Ansicht verwenden TabLayout.Tab setCustomView(android.view.View view), ist dies einfacher. So geht's in beide Richtungen.

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

Wenn Sie keine benutzerdefinierte Ansicht verwenden, können Sie dies folgendermaßen tun

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

Verwenden Sie eine StateListDrawable, um zwischen ausgewählten und nicht ausgewählten Zeichenelementen oder Ähnlichem umzuschalten und mit Farben und / oder Zeichenelementen das zu tun, was Sie möchten.

Kenodoggy
quelle
12

Einfach einstellen viewPager.setCurrentItem(index)und das zugehörige TabLayout würde die entsprechende Registerkarte auswählen.

Panduka DeSilva
quelle
Das hat bei mir nicht funktioniert. Ich musste die .post-Methode verwenden.
Arenaq
7

Sie können versuchen, es damit zu lösen:

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

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

Versuche dies

    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
quelle
Danke. Es hat für mich funktioniert. Aber ist es eine gute Praxis, verzögert zu verwenden?
Harsh Shah
Ich denke, es ist schlecht, einen Thread auf einem der Layout-Ursachen auszuführen, wenn Sie den Text für die Registerkarte vom Back-End-Server abrufen und wenn der Server aus irgendeinem Grund verzögert, wird dieser System-Thread Ihre Geräteressourcen unnötig verbrauchen.
Cammando
so hässliche Lösung
Lester
Das funktioniert bei mir nicht. Wie stelle ich sicher, dass, wenn der Benutzer auf eine Registerkarte klickt, diese Registerkartenauswahl verzögert wird? Ich kann nichts zum Arbeiten bringen. Ich habe stattdessen versucht, i == 1 zu verwenden (mViewPager.getCurrentItem () == 0), aber es funktioniert nicht und auch nichts anderes.
iBEK
5

Ein bisschen spät, könnte aber eine nützliche Lösung sein. Ich verwende mein TabLayout direkt in meinem Fragment und versuche, einen Tab ziemlich früh im Lebenszyklus des Fragments auszuwählen. Was für mich funktioniert hat, war zu warten, bis das TabLayout seine untergeordneten Ansichten mithilfe der android.view.View#postMethode gezeichnet hat . dh:

int myPosition = 0;
myFilterTabLayout.post(() -> { filterTabLayout.getTabAt(myPosition).select(); });
ahmed_khan_89
quelle
Die richtige Antwort hat bei mir funktioniert, aber eine gewisse Verzögerung wird einen schönen Effekt erzielen new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham
3

Ich bin mit TabLayout Fragmente zu wechseln. Es funktioniert größtenteils, außer wenn ich versucht habe, programmgesteuert eine Registerkarte auszuwählentab.select() , hat my TabLayout.OnTabSelectedListenerdas ausgelöstonTabSelected(TabLayout.Tab tab) , was mir viel Kummer bereitet. Ich suchte nach einer Möglichkeit, eine programmatische Auswahl zu treffen, ohne den Hörer auszulösen.

Also habe ich die Antwort von @kenodoggy an meine Verwendung angepasst. Ich hatte weiterhin ein Problem, bei dem einige der internen Objekte null zurückgaben (weil sie noch nicht erstellt wurden, weil ich onActivityResult()von meinem Fragment aus geantwortet habe, was zuvor onCreate()bei der Aktivität singleTaskoder der Fall war singleInstance), also schrieb ich ein detailliertes if auf / else Sequenz, die den Fehler meldet und durchfällt, ohne NullPointerExceptiondass dies sonst ausgelöst würde. Ich verwende Timber für die Protokollierung, wenn Sie diesen Ersatz nicht mit verwendenLog.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");
    }
}

Hier ist tabLayout meine Speichervariable, die an das TabLayoutObjekt in meinem XML gebunden ist . Und ich verwende die Funktion zum Scrollen nicht, also habe ich sie auch entfernt.

Dhiraj Gupta
quelle
3

Sie sollten einen viewPager verwenden, um viewPager.setCurrentItem () zu verwenden.

 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
quelle
2

Fügen Sie für Ihren Viewpager hinzu:

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

// auf dem Handler, um einen Absturz des Speichers zu verhindern

private void setViewPagerByIndex(final int index){
    Application.getInstance().getHandler().post(new Runnable() {
        @Override
        public void run() {
            viewPager.setCurrentItem(index);
        }
    });
}
Alex Zaraos
quelle
1
"Absturz aus dem Speicher verhindern" - warum benötigen wir einen separaten Thread, um das aktuelle Element auszuwählen?
AppiDevo
2

Eine kombinierte Lösung aus verschiedenen Antworten lautet:

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

  myViewPager.setCurrentItem(position, true);

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

Verwenden Sie mit der TabLayoutvon der Material Components Library bereitgestellten selectTabMethode einfach die folgende Methode:

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

Geben Sie hier die Bildbeschreibung ein

Es erfordert Version 1.1.0.

Gabriele Mariotti
quelle
Nein, selectTab ist eine paketprivate Methode.
XY
@ xyuber.com Ich habe eine wichtige Info hinzugefügt. Es erfordert Version 1.1.0. Die Methode ist jetzt öffentlich
Gabriele Mariotti
1

Wenn Sie eine Registerkarte auswählen, wird diese standardmäßig hervorgehoben. Wenn Sie explizit auswählen möchten, verwenden Sie den angegebenen kommentierten Code unter onTabSelected (Registerkarte TabLayout.Tab) mit der angegebenen Tab-Indexposition. In diesem Code wird das Ändern des Fragments an der auf der Registerkarte ausgewählten Position mithilfe des Viewpagers erläutert.

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

Das kann auch helfen

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 Hinweis
quelle
1

Wenn Ihre Standardregisterkarte die erste ist (0) und Sie zufällig zu einem Fragment wechseln, müssen Sie das Fragment zum ersten Mal manuell ersetzen. Dies liegt daran, dass die Registerkarte ausgewählt wird, bevor der Listener registriert wird.

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

Alternativ können Sie das Aufrufen getTabAt(0).select()und Überschreiben folgendermaßen in Betracht ziehen onTabReselected:

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

Dies würde funktionieren, da Sie das Fragment im Wesentlichen bei jeder erneuten Auswahl der Registerkarte ersetzen.

farthVader
quelle
0

Sie können die TabLayout-Position mit den folgenden Funktionen festlegen

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

Wenn Sie Probleme beim Verstehen haben, kann Ihnen dieser Code helfen

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
}

Sie können dies auch zu Ihrem Code hinzufügen:

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

Versuchen Sie es auf diese Weise.

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

Wenn Sie TabLayout ohne viewPager verwenden, hilft dies

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

Kotlin reparieren

viewPager.currentItem = 0

tabs.setupWithViewPager (viewPager)

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

Dadurch wird die Registerkarte als Seite zum Anzeigen des Pager-Swipe ausgewählt

Rachit Vohera
quelle