Вибір вкладки TabLayout


Відповіді:


418

Якщо ви знаєте індекс вкладки, яку ви хочете вибрати, ви можете це зробити так:

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

Ця методика працює, навіть якщо ви використовуєте TabLayout самостійно без ViewPager (що є нетиповим і, ймовірно, поганою практикою, але я бачив це).


10
Це рішення працює лише в тому випадку, якщо в панель дій додана вкладка, що може не завжди бути таким. З документації для TabLayout.Tab.select(): "Виберіть цю вкладку. Дійсно лише в тому випадку, якщо вкладка була додана до панелі дій."
Даніель Квіст

7
@DanielKvist, насправді сама документація неправильна. Вихідний код говорить сам за себе. Ця відповідь має бути прийнятою відповіддю.
Джейсон Спарк

@JasonSparc Хм, я пам’ятаю, що він не працював на мене, коли я востаннє спробував це рішення, але я побачу, чи можу я перевірити двічі перевірити, як воно працює для мене. Ти намагався? Це може спрацювати в деяких випадках, а в інших випадках? Це може залежати від рівня API чи чогось подібного?
Даніель Квіст

Дякуємо, що очистили Повітря на напівприготовлені відповіді! Тому що це просто не працює на самостійному TabLayout, ймовірно, з причини, яку ви заявили; Це призначено для роботи з Tabs на панелі дій!
sud007

3
Чому використання TabLayout без ViewPager слід вважати поганою практикою?
tomalf2

85

Ось як я це вирішив:

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

3
Вибрана відповідь не працювала для мене, але ця.
Рафал Завадзкі

чудове рішення! добре працював для мене, коли мені потрібно було повернутися на першу сторінку і viewPager, і TabView
sashk0

49

Використовуй це:

tabs.getTabAt(index).select();

дякую, це безпечне рішення щодо мого втілення
islam farid

Objects.requireNonNull(tabs.getTabAt(position)).select();безпечний у користуванні
Вілліан Лопес

1
Майте на увазі, що якщо currentTabIndex та індекс однакові, то це посилає ваш потік на onTabReselected, а не onTabSelected.
Абхішек Кумар

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

Я перевірив, наскільки великим є вплив використання цього коду, спочатку переглянувши монітори процесора та пам'яті в Android Studio під час використання методу, а потім порівняв його з навантаженням, яке було покладено на процесор і пам'ять, коли я переходив між сторінками Я (використовуючи жести пальцями), і різниця не суттєво велика, тому принаймні це не жахливе рішення ...

Сподіваюся, це комусь допоможе!


1
Коли я робив рішення dap ( tabLayout.setScrollPosition(pageIndex,0f,true);), коли натискав на вкладку праворуч, він не оновлював сторінку ViewPager (не знаю чому). Лише натискання назад на лівій вкладці та потім на правій вкладці, нарешті, оновить сторінку, щоб мати сторінку правої вкладки, яка є дуже глянцевою. Але це рішення не мало жодних збоїв.
Рок Лі

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 для перемикання між вибраними та невибраними малюнками або чимось подібним, щоб робити те, що ви хочете, з кольорами та / або малюнками.


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

Thanks.it працював на мене. Але чи корисна практика використовувати відкладені?
Суворий Шах

Я думаю, що погано запускати потік на будь-якій причині компонування, якщо припустимо, що ви надсилаєте текст для вкладки із сервера, що працює з заднім числом, і якщо через будь-яку причину сервер затримується, ця системна нитка неминуче споживає ресурси вашого пристрою.
каммандо

настільки потворне рішення
Лестер

Це не працює для мене. Як зробити так, що якщо користувач натискає вкладку, то затримувати вибір цього вкладки? Я нічого не можу змусити працювати. Я намагався замість цього, якщо я == 1 використовувати (mViewPager.getCurrentItem () == 0), але він не працює, і нічого іншого не робить.
iBEK

5

Трохи пізно, але може бути корисним рішенням. Я використовую свій TabLayout безпосередньо у своєму фрагменті і намагаюся вибрати вкладку досить рано у життєвому циклі фрагмента. Що для мене спрацювало - чекати, поки TabLayout закінчить малювати свої дитячі погляди за допомогою android.view.View#postметоду. тобто:

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

правильна відповідь спрацювала для мене, але деяка затримка дасть це приємний ефект new Handler().postDelayed(()->{ tabLayout.post(() -> { tabLayout.getTabAt(myPosition).select(); }); },200);
Хішам

3

Я маю в використанні TabLayout для перемикання фрагментів. Він працює здебільшого, за винятком випадків, коли я намагався програмно вибрати вкладку tab.select(), мій TabLayout.OnTabSelectedListenerзапустив биonTabSelected(TabLayout.Tab tab) , що спричинило б мені багато горя. Я шукав спосіб зробити програмний відбір, не викликаючи слухача.

Тому я адаптував відповідь @kenodoggy на моє використання. Далі я зіткнувся з проблемою, коли деякі внутрішні об’єкти повернуться до нуля (тому що вони ще не були створені, тому що я відповідав onActivityResult()із мого фрагмента, який виникає раніше onCreate()у випадку активності singleTaskабо singleInstance), тому я записав детальний, якщо / else послідовність, яка повідомила б про помилку і провалилася без того, NullPointerExceptionщо інакше призведе до запуску. Я використовую Timber для ведення журналу, якщо ви не використовуєте цей замінник 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) {
            }
        });

// на оброблювачем для запобігання аварійних перешкод

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

1
"запобігти аварійній роботі" - навіщо нам потрібен окремий потік для вибору поточного елемента?
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. Метод відкритий зараз
Габріеле

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

це вибере вкладку як перегляд сторінки пейджера

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.