Выбор вкладки 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, вероятно, по причине, которую вы указали; Он предназначен для работы с вкладками в панели действий!
— 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();

спасибо, это безопасное решение для моей реализации
— Ислам Фарид

Objects.requireNonNull(tabs.getTabAt(position)).select();безопасно использовать
— Williaan Lopes

1
Имейте в виду, что если currentTabIndex и index совпадают, то это отправляет ваш поток в onTabReselected, а не в onTabSelected.
— Абхишек Кумар

@WilliaanLopes, это не защитит вас от NPI, просто бросит его раньше
— Кшиштоф Кубицкий

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

Я думаю, то же самое, пожалуйста, сначала попробуйте это.
— Правин Сутар

23

Это, вероятно, не окончательное решение , и оно требует, чтобы вы использовали TabLayoutвместе с aViewPager , но я решил это так:

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

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

Надеюсь, это поможет кому-то!


1
Когда я делал dap's solution ( 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();
}

6

Немного поздно, но может быть полезным решением. Я использую свой 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);
— Хишам

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

Спасибо. Это сработало для меня. Но стоит ли использовать задержку?
— Суровый шах

Я полагаю, что запускать потоки на любой из причин компоновки нехорошо, если предположим, что вы извлекаете текст для вкладки с внутреннего сервера, и если по какой-либо причине b'coz задерживает работу сервера, этот системный поток излишне потребляет ресурсы вашего устройства.
— Каммандо

такое уродливое решение
— Лестер

Это не работает для меня. Как сделать так, чтобы, если пользователь щелкает вкладку, то задерживает выбор этой вкладки? Я ничего не могу заставить работать. Вместо этого я попытался использовать i == 1 (mViewPager.getCurrentItem () == 0), но он не работает и ничего не делает.
— iBEK

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 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.