Выбор вкладки 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.