131

Wie Registerkarte in TabLayout programmgesteuert auswählen?TabLayout Registerkarte Auswahl

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
tabLayout.setupWithViewPager(viewPager); 
+1

bitte markieren Sie eine Antwort als die richtige. Es hilft ! – eRaisedToX

Antwort

247

Wenn Sie den Index der Registerkarte wissen Sie auswählen möchten, können Sie es wie so tun:

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

Diese Technik funktioniert auch, wenn Sie die TabLayout selbst verwenden ohne ViewPager (Das ist untypisch und wahrscheinlich schlechte Praxis, aber ich habe es gesehen).

+8

Diese Lösung funktioniert nur, wenn die Registerkarte der 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 der Aktionsleiste hinzugefügt wurde." * –

+3

@DanielKvist, eigentlich ist die Dokumentation selbst falsch. Der Quellcode spricht für sich. Diese Antwort sollte die akzeptierte Antwort sein. –

+0

@JasonSparc Hmm, ich erinnere mich, es funktioniert nicht für mich, wenn ich diese Lösung zuletzt versuchte, aber ich werde sehen, ob ich überprüfen kann, wie es für mich funktioniert. Hast du es versucht? Es könnte in einigen Fällen funktionieren, in anderen nicht? Es könnte auf API-Ebene oder etwas ähnliches abhängen? –

16

Dies ist wahrscheinlich nicht die ultimative Lösung und es, dass Sie die TabLayout zusammen mit einem ViewPager, aber das ist verwenden erfordert, wie ich es gelöst:

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

ich, wie groß die Leistung getestet Die Auswirkung dieses Codes besteht darin, zunächst die CPU- und Speicher-Monitore in Android Studio zu betrachten, während die Methode ausgeführt wird, und sie dann mit der Last zu vergleichen, die auf die CPU und den Speicher geladen wurde, wenn ich selbst zwischen den Seiten navigierte (mit Swipe-Gesten). und der Unterschied ist nicht signifikant groß, also ist es zumindest keine schreckliche Lösung ...

Hoffe das hilft jemandem! Diese

+1

Wenn ich die Lösung von dap ('tabLayout.setScrollPosition (pageIndex, 0f, true);'), wenn ich auf die Registerkarte auf der rechten Seite geklickt hat, aktualisiert es nicht die ViewPager-Seite (Ich weiß nicht warum). Wenn Sie nur auf den linken und dann auf den rechten Tab klicken, wird die Seite schließlich aktualisiert, um die richtige Tab-Seite zu erhalten, was sehr störend ist. Aber diese Lösung hatte keine Störungen. –

54

ist, wie ich es gelöst:

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

Ausgewählte Antwort funktionierte nicht für mich, aber dieses hat. –

+0

großartige Lösung! funktionierte gut für mich, als ich wieder auf die erste Seite sowohl ViewPager und TabView – sashk0

+0

Worked für mich arbeiten musste. Vielen Dank. –

11

Wenn Sie nicht verwenden tab.select können(), und Sie wollen nicht zu einem ViewPager verwenden, können Sie immer noch programmatisch wählen Sie eine Registerkarte. Wenn Sie eine benutzerdefinierte Ansicht über TabLayout.Tab setCustomView(android.view.View view) verwenden, ist es einfacher. Hier ist, wie es in beide Richtungen geht.

// 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 nicht eine benutzerdefinierte Ansicht dann verwenden, können Sie es tun, wie diese

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

ein StateListDrawable Verwenden Sie zwischen ausgewählten und nicht ausgewählten Drawables oder etwas ähnliches zu tun, was Sie mit Farben wollen wechseln und/oder Zeichen.

1

Wenn Sie eine Registerkarte auswählen, wird sie standardmäßig hervorgehoben. Wenn Sie Explicitly auswählen möchten, verwenden Sie den angegebenen kommentierten Code unter onTabSelected (Registerkarte TabLayout.Tab) mit der angegebenen Registerindexposition. Dieser Code erläutert das Ändern des Fragments auf der ausgewählten Registerkarte mithilfe von 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); 
    } 
} 
} 
10

Verwendung tabs.getTabAt(2).select();

2

für Ihren viewpager hinzufügen:

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 Handler Absturz OutOfMemory

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

"verhindern Absturz outofmemory" - warum brauchen wir einen separaten Thread, um aktuelle Artikel auszuwählen? – AppiDevo

6

versuchen, diese

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); 
zu verhindern diese
+0

Thanks.it arbeitete für mich. Aber ist es eine gute Übung, verzögert zu verwenden? –

+0

Ich denke, es ist schlecht, Thread auf einem der Layout-Ursache zu führen, wenn Sie annehmen, dass Sie den Text für die Registerkarte vom Back-End-Server holen und wenn b'coz aus irgendeinem Grund der Server Verzögerungen dann wird diese System-Thread Ihre Gerät Ressourcen unnötig verbrauchen. – cammando

+0

so hässliche Lösung – Lester

12

Verwendung:

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

die beste Antwort :) –

+0

Dies sollte als richtig markiert werden – marchinram

1

I am TabLayout mit Fragmenten zu wechseln. Es funktioniert größtenteils, außer wenn ich versuchte, eine Registerkarte programmgesteuert unter Verwendung tab.select() zu wählen, würde meine TabLayout.OnTabSelectedListener die onTabSelected(TabLayout.Tab tab) auslösen, die mir viel Kummer verursachen würde. Ich suchte nach einer Möglichkeit, programmatische Auswahl zu treffen, ohne den Hörer auszulösen.

Also habe ich die @kenodoggy Antwort auf meine Verwendung angepasst. Ich war weiter mit einem Problem konfrontiert, wo einige der internen Objekte null zurückgaben (weil sie noch nicht erstellt wurden, weil ich von meinem Fragment beantwortete, das vor onCreate() in Fall auftritt, ist die Aktivität singleTask oder singleInstance), also schrieb ich up eine detaillierte if/else-Sequenz, die den Fehler melden würde und ohne die NullPointerException, die sonst auslösen würde. Ich benutze Timber für die Protokollierung, wenn Sie diesen Ersatz nicht mit Log.e() verwenden. Hier

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

ist tabLayout mein Speichervariable auf das in meinem XML TabLayout Objekt gebunden. Und ich benutze nicht die Scrolling-Tab-Funktion, also habe ich das auch entfernt.

2

Sie können versuchen, es mit dieser Lösung:

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

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

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

Stellen Sie einfach viewPager.setCurrentItem(index) und der damit verbundene TabLayout würde die entsprechenden Registerkarte auswählen.

0

Sie können einstellen, TabLayout Position folgende Funktionen

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

Wenn es so, dass Tab Ihr Standard passiert, ist die erste (0) und Sie zufällig auf ein Fragment wechseln, dann müssen Sie manuell das Fragment ersetzen zum ersten Mal. Dies liegt daran, dass die Registerkarte ausgewählt ist, 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 betrachten getTabAt(0).select() und überwiegende onTabReselected wie so nennen:

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

Dies würde funktionieren, weil Sie im Wesentlichen ist das Fragment auf jedem Registerkarte neu wählen zu ersetzen.