TabLayout การเลือกแท็บ


คำตอบ:


418

หากคุณรู้จักดัชนีของแท็บที่คุณต้องการเลือกคุณสามารถทำได้โดยทำดังนี้

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

เทคนิคนี้ใช้งานได้แม้ว่าคุณจะใช้ TabLayout ด้วยตัวเองโดยไม่มี ViewPager (ซึ่งผิดปรกติและอาจเป็นแนวปฏิบัติที่ไม่ดี แต่ฉันเคยเห็นมาแล้ว)


10
โซลูชันนี้ใช้งานได้เฉพาะเมื่อมีการเพิ่มแท็บในแถบแอ็คชันซึ่งอาจไม่ใช่ทุกกรณี จากเอกสารสำหรับTabLayout.Tab.select(): "เลือกแท็บนี้ใช้ได้เฉพาะเมื่อมีการเพิ่มแท็บในแถบการกระทำ"
Daniel Kvist

7
@DanielKvist จริง ๆ แล้วเอกสารเองไม่ถูกต้อง รหัสแหล่งที่มาพูดสำหรับตัวเอง คำตอบนี้ควรเป็นคำตอบที่ยอมรับได้
Jason Sparc

@ JasonSparc อืมฉันจำได้ว่ามันไม่ทำงานสำหรับฉันเมื่อฉันลองใช้วิธีแก้ไขปัญหานี้ครั้งสุดท้าย แต่ฉันจะดูว่าฉันสามารถตรวจสอบอีกครั้งตรวจสอบวิธีการทำงานสำหรับฉัน คุณเคยลองไหม อาจใช้งานได้ในบางกรณี แต่ไม่ใช่ในกรณีอื่น? มันอาจขึ้นอยู่กับระดับ API หรืออะไรที่คล้ายกัน?
Daniel Kvist

ขอบคุณสำหรับการล้างอากาศด้วยคำตอบที่ปรุงสุกแล้วครึ่งหนึ่ง! เพราะนั่นไม่ได้ผลกับ TabLayout แบบสแตนด์อโลนอาจเป็นเพราะเหตุผลที่คุณระบุ มันทำงานร่วมกับแท็บใน Actionbar ได้แล้ว!
sud007

3
เหตุใดการใช้ TabLayout โดยไม่มี ViewPager จึงควรได้รับการพิจารณาว่าไม่เหมาะสม
tomalf2

85

นี่คือวิธีที่ฉันแก้ไขมัน:

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

3
คำตอบที่เลือกไม่ได้ผลสำหรับฉัน แต่อันนี้ใช้ได้
Rafal Zawadzki

ทางออกที่ดี! ปรับทำงานสำหรับฉันเมื่อฉันต้องการที่จะย้ายกลับไปที่หน้าแรกของทั้งสอง viewPager และ TabView
sashk0

49

ใช้สิ่งนี้:

tabs.getTabAt(index).select();

ขอบคุณนี่เป็นทางออกที่ปลอดภัยสำหรับ implementaion ของฉัน
islam farid

Objects.requireNonNull(tabs.getTabAt(position)).select();ปลอดภัยในการใช้
Williaan Lopes

1
โปรดทราบว่าหาก currentTabIndex และดัชนีเหมือนกันสิ่งนี้จะส่งโฟลว์ของคุณไปยัง onTabReselected และไม่ใช่ onTabSelected
Abhishek Kumar

@WilliaanLopes นี้จะไม่ปกป้องคุณจาก NPI เพียงแค่จะโยนมันเร็วขึ้น
Krzysztof Kubicki

33

ใช้สิ่งนี้:

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

หลังจากอยู่ใน OnClickListener:

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

เกิดอะไรขึ้นถ้า tabMode สามารถเลื่อนได้?
GvSharma

ฉันคิดเหมือนกันก่อนอื่นคุณลองที่
Pravin Suthar

23

นี่อาจไม่ใช่ทางออกที่ดีที่สุดและคุณต้องใช้TabLayoutพร้อมกับ aViewPagerแต่นี่คือวิธีที่ฉันแก้ไข:

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

ฉันทดสอบว่าประสิทธิภาพของการใช้รหัสนี้มากแค่ไหนโดยดูที่หน้าจอ CPU- และหน่วยความจำใน Android Studio ในขณะที่ใช้วิธีการจากนั้นเปรียบเทียบกับภาระที่วางบน CPU และหน่วยความจำเมื่อฉันสำรวจระหว่างหน้าต่างๆ ตัวฉัน (ใช้การปัดนิ้ว) และความแตกต่างก็ไม่ใหญ่มากดังนั้นอย่างน้อยมันก็ไม่ใช่ทางออกที่น่ากลัว ...

หวังว่านี่จะช่วยใครซักคน!


1
เมื่อฉันทำโซลูชันของ dap ( tabLayout.setScrollPosition(pageIndex,0f,true);) เมื่อฉันคลิกที่แท็บทางด้านขวาจะไม่อัปเดตหน้าของ ViewPager (ฉันไม่ทราบสาเหตุ) เพียงคลิกที่แท็บด้านซ้ายแล้วบนแท็บด้านขวาอีกครั้งในที่สุดจะอัปเดตหน้าให้มีหน้าของแท็บที่ถูกต้องซึ่งมีความผิดพลาดมาก แต่วิธีนี้ไม่มีข้อบกพร่อง
Rock Lee

12

หากคุณไม่สามารถใช้ tab.select () และคุณไม่ต้องการใช้ ViewPager คุณยังสามารถเลือกแท็บโดยทางโปรแกรมได้ หากคุณใช้มุมมองที่กำหนดเองTabLayout.Tab setCustomView(android.view.View view)มันจะง่ายกว่า นี่คือวิธีการทำทั้งสองวิธี

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

หากคุณไม่ได้ใช้มุมมองที่กำหนดเองคุณสามารถทำสิ่งนี้ได้

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

ใช้ StateListDrawable เพื่อสลับระหว่าง drawable ที่เลือกและไม่ได้เลือกหรือสิ่งที่คล้ายกันเพื่อทำสิ่งที่คุณต้องการด้วยสีและ / หรือ drawable


12

เพียงแค่ตั้งค่าviewPager.setCurrentItem(index)และ TabLayout ที่เกี่ยวข้องจะเลือกแท็บที่เกี่ยวข้อง


สิ่งนี้ไม่ได้ผลสำหรับฉัน ฉันต้องใช้วิธีการ. post
arenaq

7

คุณสามารถลองแก้ปัญหาด้วยสิ่งนี้:

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

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

5

ลองนี้

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

ขอบคุณมันใช้ได้สำหรับฉัน แต่เป็นวิธีปฏิบัติที่ดีที่จะใช้งานล่าช้าหรือไม่
Harsh Shah

ฉันคิดว่ามันไม่ดีที่จะเรียกใช้เธรดบนเค้าโครงใด ๆ หากสมมติว่าคุณดึงข้อความสำหรับแท็บจากเซิร์ฟเวอร์แบ็กเอนด์และถ้า b'coz ไม่ว่าด้วยเหตุผลใดก็ตามที่เซิร์ฟเวอร์เกิดความล่าช้าระบบเธรดนี้จะใช้ทรัพยากรอุปกรณ์ของคุณ
cammando

วิธีแก้ปัญหาที่น่าเกลียดมาก
เลสเตอร์

มันไม่ได้ผลสำหรับฉัน ฉันจะทำอย่างไรหากผู้ใช้คลิกที่แท็บแล้วเลื่อนการเลือกแท็บนั้นออกไป ฉันไม่สามารถทำงานอะไรได้ ฉันพยายามแทนถ้าฉัน == 1 ใช้ (mViewPager.getCurrentItem () == 0) แต่มันใช้งานไม่ได้และไม่ทำอะไรเลย
iBEK

5

สายไปหน่อย แต่อาจเป็นทางออกที่มีประโยชน์ ฉันใช้ TabLayout ของฉันโดยตรงใน Fragment ของฉันและพยายามเลือกแท็บค่อนข้างเร็วในวงจรชีวิตของ Fragment สิ่งที่ใช้ได้ผลสำหรับฉันคือรอจนกว่า TabLayout วาดมุมมองลูกของมันโดยใช้ android.view.View#postวิธีการ เช่น:

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

คำตอบที่ถูกต้องทำงานให้ฉัน แต่ความล่าช้าบางจะให้มันมีผลดี new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham

3

ฉันกำลังใช้ TabLayout สลับชิ้นส่วน มันใช้งานได้เป็นส่วนใหญ่ยกเว้นทุกครั้งที่ฉันพยายามเลือกแท็บที่ใช้โดยทางโปรแกรมtab.select()ฉันTabLayout.OnTabSelectedListenerจะเรียกใช้onTabSelected(TabLayout.Tab tab)ซึ่งจะทำให้ฉันเสียใจมาก ฉันกำลังมองหาวิธีที่จะทำการเลือกแบบเป็นโปรแกรมโดยไม่ทริกเกอร์ผู้ฟัง

ดังนั้นฉันจึงปรับคำตอบของ @kenodoggy ให้เหมาะกับการใช้งานของฉัน ฉันกำลังเผชิญกับปัญหาที่วัตถุภายในบางอย่างจะส่งคืนค่าว่าง (เพราะพวกเขายังไม่ได้สร้างขึ้นเพราะฉันตอบonActivityResult()กลับมาจากส่วนของฉันซึ่งเกิดขึ้นก่อนหน้านี้onCreate()ในกรณีที่กิจกรรมเป็นsingleTaskหรือsingleInstance) ดังนั้นฉันจึงเขียนรายละเอียดว่า / else ลำดับซึ่งจะรายงานข้อผิดพลาดและล้มลงโดยไม่มีสิ่งใดNullPointerExceptionที่จะทริกเกอร์ 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 เป็นตัวแปรหน่วยความจำของฉันถูกผูกไว้กับTabLayoutวัตถุใน XML ของฉัน และฉันไม่ได้ใช้คุณสมบัติแท็บการเลื่อนดังนั้นฉันจึงลบออกเช่นกัน


3

คุณควรใช้ viewPager เพื่อใช้ 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

เพิ่มสำหรับผู้ดูของคุณ:

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

// บนตัวจัดการเพื่อป้องกันความผิดพลาด outofmemory

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

1
"ป้องกันความผิดพลาด outofmemory" - เหตุใดเราจึงต้องแยกเธรดเพื่อเลือกรายการปัจจุบัน
AppiDevo

2

โซลูชันที่รวมกันจากคำตอบที่แตกต่างกันคือ:

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

  myViewPager.setCurrentItem(position, true);

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

2

ด้วยไลบรารีวัสดุที่TabLayoutมีให้โดยใช้วิธีการ:selectTab

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

ป้อนคำอธิบายรูปภาพที่นี่

ต้องใช้เวอร์ชัน 1.1.0


ไม่, selectTab เป็นวิธีการส่วนตัว
XY

@ xyuber.com ฉันได้เพิ่มข้อมูลสำคัญ ต้องใช้เวอร์ชัน 1.1.0 วิธีนี้เป็นแบบสาธารณะในขณะนี้
Gabriele Mariotti

1

โดยค่าเริ่มต้นหากคุณเลือกแท็บจะมีการเน้นสี หากคุณต้องการเลือกอย่างชัดเจนหมายถึงใช้รหัสที่ได้รับความเห็นภายใต้ onTabSelected (แท็บ TabLayout.Tab) ด้วยตำแหน่งดัชนีแท็บที่คุณระบุ รหัสนี้จะอธิบายเกี่ยวกับการเปลี่ยนแปลงส่วนในแท็บตำแหน่งที่เลือกโดยใช้ 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

สิ่งนี้สามารถช่วยได้เช่นกัน

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

หากเป็นเช่นนั้นแท็บเริ่มต้นของคุณคือแท็บแรก (0) และคุณเกิดการสลับเป็นแฟรกเมนต์คุณต้องเปลี่ยนแฟรกเมนต์ด้วยตนเองเป็นครั้งแรก นี่เป็นเพราะแท็บถูกเลือกก่อนที่ผู้ฟังจะลงทะเบียน

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

อีกทางเลือกหนึ่งคุณสามารถพิจารณาการโทรgetTabAt(0).select()และการเอาชนะonTabReselectedเช่น:

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

สิ่งนี้จะได้ผลเพราะคุณต้องเปลี่ยนชิ้นส่วนใหม่ในทุกแท็บใหม่


0

คุณสามารถตั้งค่าตำแหน่ง TabLayout โดยใช้ฟังก์ชั่นต่อไปนี้

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

0

หากคุณมีปัญหาในการทำความเข้าใจรหัสนี้สามารถช่วยคุณได้

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
}

คุณสามารถเพิ่มรหัสนี้ในรหัสของคุณ:

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

0

ลองด้วยวิธีนี้

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

0

ถ้าคุณใช้ TabLayout โดยไม่ต้องใช้ viewPager สิ่งนี้จะช่วย

 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
TabLayout jobTabs = v.findViewById(R.id.jobTabs);
ViewPager jobFrame = v.findViewById(R.id.jobPager);
jobFrame.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(jobTabs));

นี่จะเป็นการเลือกแท็บในการดูเพจปัดหน้าเพจเจอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.