Lựa chọn tab TabLayout


Câu trả lời:


418

Nếu bạn biết chỉ mục của tab bạn muốn chọn, bạn có thể làm như vậy:

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

Kỹ thuật này hoạt động ngay cả khi bạn đang sử dụng TabLayout một mình mà không có ViewPager (không điển hình và có thể là thực tiễn xấu, nhưng tôi đã thấy nó được thực hiện).


10
Giải pháp này chỉ hoạt động nếu tab đã được thêm vào thanh hành động, có thể không phải luôn luôn như vậy. Từ tài liệu cho TabLayout.Tab.select(): "Chọn tab này. Chỉ hợp lệ nếu tab đã được thêm vào thanh hành động."
Daniel Kvist

7
@DanielKvist, thực sự tài liệu không chính xác. Mã nguồn nói cho chính nó. Câu trả lời này phải là câu trả lời được chấp nhận.
Jason Sparc

@JasonSparc Hmm, tôi nhớ nó không hoạt động với tôi khi tôi dùng thử giải pháp này lần cuối, nhưng tôi sẽ xem liệu tôi có thể kiểm tra lại xem nó hoạt động như thế nào với tôi không. Bạn đã thử chưa Nó có thể hoạt động trong một số trường hợp, trong khi không phải trong các trường hợp khác? Nó có thể phụ thuộc vào cấp độ API hoặc một cái gì đó tương tự?
Daniel Kvist

Cảm ơn đã xóa Air trên một nửa câu trả lời nấu chín! Bởi vì điều đó chỉ không hoạt động trên TabLayout độc lập có thể vì lý do bạn đã nêu; Nó có nghĩa là để làm việc với các Tab trong Actionbar!
sud007

3
Tại sao sử dụng TabLayout mà không có ViewPager nên được coi là thực tiễn xấu?
tomalf2

84

Đây là cách tôi giải quyết nó:

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

3
Câu trả lời được chọn không làm việc cho tôi, nhưng câu trả lời này đã làm.
Rafal Zawadzki

giải pháp tuyệt vời! làm việc tốt với tôi, khi tôi cần quay lại trang đầu tiên cả viewPager và TabView
sashk0

49

Dùng cái này:

tabs.getTabAt(index).select();

cảm ơn, đây là một giải pháp an toàn cho việc triển khai của tôi
islam far

Objects.requireNonNull(tabs.getTabAt(position)).select();an toàn khi sử dụng
Williaan Lopes

1
Hãy nhớ rằng, nếu currentTab Index và chỉ mục giống nhau thì điều này sẽ gửi luồng của bạn đến onTabReselected chứ không phải onTabSelected.
Abhishek Kumar

@WilliaanLopes, điều này sẽ không bảo vệ bạn khỏi NPI, sẽ ném nó sớm hơn
Krzysztof Kubicki

33

Dùng cái này:

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

Sau khi vào OnClickListener:

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

Điều gì nếu tabMode có thể cuộn được?
GvSharma

Tôi cũng nghĩ như vậy, trước tiên bạn hãy thử nó.
Pravin Suthar

23

Đây có lẽ không phải là giải pháp tối ưunó yêu cầu bạn sử dụng TabLayoutcùng với aViewPager , nhưng đây là cách tôi giải quyết nó:

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

Tôi đã kiểm tra mức độ ảnh hưởng hiệu năng của việc sử dụng mã này lớn như thế nào bằng cách trước tiên nhìn vào màn hình CPU và bộ nhớ trong Android Studio trong khi chạy phương thức, sau đó so sánh nó với tải được đặt trên CPU và bộ nhớ khi tôi điều hướng giữa các trang bản thân tôi (sử dụng cử chỉ vuốt) và sự khác biệt không đáng kể, vì vậy ít nhất đó không phải là một giải pháp khủng khiếp ...

Hy vọng điều này sẽ giúp được ai đó!


1
Khi tôi thực hiện giải pháp của dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), khi tôi nhấp vào tab bên phải, nó không cập nhật trang ViewPager's (tôi không biết tại sao). Chỉ nhấp lại vào tab bên trái và sau đó trên tab bên phải một lần nữa cuối cùng sẽ cập nhật trang để có trang của tab bên phải, rất rối mắt. Nhưng giải pháp này không có trục trặc.
Rock Lee

12

Nếu bạn không thể sử dụng tab.select () và bạn không muốn sử dụng ViewPager, bạn vẫn có thể chọn một tab theo chương trình. Nếu bạn đang sử dụng chế độ xem tùy chỉnh thông qua TabLayout.Tab setCustomView(android.view.View view)nó thì đơn giản hơn. Đây là cách làm cả hai cách.

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

Nếu bạn không sử dụng chế độ xem tùy chỉnh thì bạn có thể làm như thế này

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

Sử dụng StateListDrawable để chuyển đổi giữa các drawable được chọn và không được chọn hoặc một cái gì đó tương tự để làm những gì bạn muốn với màu sắc và / hoặc drawables.


12

Chỉ cần đặt viewPager.setCurrentItem(index)và TabLayout được liên kết sẽ chọn tab tương ứng.


Điều này đã không làm việc cho tôi. Tôi đã phải sử dụng phương pháp .post.
Arenaq

7

Bạn có thể thử giải quyết nó bằng cách này:

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

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

5

thử cái này

    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 đã làm việc cho tôi. Nhưng nó là thực hành tốt để sử dụng chậm trễ?
Harsh Shah

Tôi đoán thật tệ khi chạy luồng trên bất kỳ nguyên nhân bố cục nào nếu giả sử bạn đang tìm nạp văn bản cho tab từ máy chủ phụ trợ và nếu vì lý do nào đó, máy chủ sẽ trì hoãn thì chủ đề hệ thống này sẽ tiêu tốn tài nguyên thiết bị của bạn một cách hoàn hảo.
cammando

giải pháp quá xấu xí
Lester

Điều này không làm việc cho tôi. Làm thế nào để tôi biết rằng nếu người dùng nhấp vào một tab, sau đó trì hoãn lựa chọn tab đó? Tôi không thể làm gì được. Thay vào đó, tôi đã thử sử dụng nếu i == 1 để sử dụng (mViewPager.getCienItem () == 0) nhưng nó không hoạt động và không làm gì khác.
iBEK

5

Một chút muộn nhưng có thể là một giải pháp hữu ích. Tôi đang sử dụng TabLayout trực tiếp trong Fragment của mình và cố gắng chọn một tab khá sớm trong Vòng đời của Fragment. Điều làm việc cho tôi là đợi cho đến khi TabLayout hoàn thành việc vẽ các khung nhìn con của nó bằng android.view.View#postphương thức. I E:

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

câu trả lời đúng có hiệu quả với tôi nhưng một số chậm trễ sẽ mang lại hiệu quả tốt new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Hisham

3

Tôi đang sử dụng TabLayout để chuyển các đoạn. Nó hoạt động với hầu hết các phần, ngoại trừ bất cứ khi nào tôi cố gắng chọn một tab lập trình bằng cách sử dụng tab.select(), tôi TabLayout.OnTabSelectedListenersẽ kích hoạt onTabSelected(TabLayout.Tab tab), điều này sẽ khiến tôi rất đau buồn. Tôi đang tìm kiếm một cách để lựa chọn chương trình mà không kích hoạt người nghe.

Vì vậy, tôi đã điều chỉnh câu trả lời của @kenodoggy cho việc sử dụng của mình. Tôi đã phải đối mặt với một vấn đề trong đó một số đối tượng bên trong sẽ trả về null (vì chúng chưa được tạo, vì tôi đã trả lời onActivityResult()từ đoạn của mình, xảy ra trước đó onCreate()trong trường hợp hoạt động là singleTaskhoặc singleInstance) vì vậy tôi đã viết chi tiết nếu / trình tự khác sẽ báo cáo lỗi và rơi vào mà không có NullPointerExceptionđiều đó sẽ kích hoạt. Tôi sử dụng Gỗ để ghi nhật ký, nếu bạn không sử dụng thay thế đó 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");
    }
}

Ở đây, tabLayout là biến bộ nhớ của tôi được liên kết với TabLayoutđối tượng trong XML của tôi. Và tôi không sử dụng tính năng tab cuộn nên tôi cũng loại bỏ nó.


3

bạn nên sử dụng viewPager để sử dụng viewPager.setCienItem ()

 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

thêm cho người xem của bạn:

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

// trên handler để ngăn chặn sự cố outofmemory

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

1
"Ngăn chặn sự cố outofmemory" - tại sao chúng ta cần luồng riêng để chọn mục hiện tại?
AppiDevo

2

Một giải pháp kết hợp từ các câu trả lời khác nhau là:

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

  myViewPager.setCurrentItem(position, true);

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

2

Với Thư viện Thành phần Vật liệuTabLayout được cung cấp, chỉ cần sử dụng phương thức:selectTab

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

nhập mô tả hình ảnh ở đây

Nó yêu cầu phiên bản 1.1.0.


Không, selectTab là một phương thức gói riêng.
XY

@ xyuber.com Tôi đã thêm một thông tin quan trọng. Nó yêu cầu phiên bản 1.1.0. Phương pháp này được công khai ngay bây giờ
Gabriele Mariotti

1

Theo mặc định, nếu bạn chọn một tab, nó sẽ được tô sáng. Nếu bạn muốn chọn Rõ ràng có nghĩa là sử dụng mã nhận xét đã cho trong onTabSelected (tab TabLayout.Tab) với vị trí chỉ mục tab được chỉ định của bạn. Mã này sẽ giải thích về việc thay đổi đoạn trên vị trí đã chọn bằng cách sử dụng 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

Điều này cũng có thể giúp

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

Nếu điều đó xảy ra thì tab mặc định của bạn là tab đầu tiên (0) và bạn tình cờ chuyển sang một đoạn, thì bạn phải thay thế thủ công đoạn đó lần đầu tiên. Điều này là do tab được chọn trước khi người nghe được đăng ký.

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

Ngoài ra, bạn có thể xem xét việc gọi getTabAt(0).select()và ghi đè onTabReselectednhư vậy:

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

Điều này sẽ hoạt động vì về cơ bản bạn đang thay thế đoạn trên mỗi tab chọn lại.


0

Bạn có thể đặt vị trí TabLayout bằng các chức năng sau

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

0

Nếu bạn gặp khó khăn trong việc hiểu, mã này có thể giúp bạn

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
}

Bạn cũng có thể thêm mã này vào mã của mình:

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

0

Hãy thử cách này.

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

0

nếu bạn đang sử dụng TabLayout mà không có viewPager thì điều này sẽ giúp

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

Điều này sẽ chọn tab khi xem trang vuốt trang

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.