Как использовать TabLayout с ViewPager2 в Android

Я хочу использовать компонент com.google.android.material.tabs.TabLayout с новой ViewPager реализацией Android androidx.viewpager2.widget.ViewPager2. Однако метод setupWithViewPager(..), предоставляемый TabLayout, поддерживает только старую реализацию ViewPager. Есть ли способ легко привязать TabLayout к ViewPager2 компоненту?

Возможно, этот пример ViewPager2 от Google поможет: github.com/android/views-widgets-samples/tree/master/ViewPag‌​er2

IgorGanapolsky 04.03.2020 01:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
77
1
77 390
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Ответ принят как подходящий

Вы должны использовать этоTabLayoutMediator, который имитирует tabLayout.setupWithViewPager() и устанавливает ViewPager2 с Tablayout. В противном случае вам придется писать собственный адаптер, который будет совмещать обе стороны.

Его код будет выглядеть так в Котлине

TabLayoutMediator(tabLayout, viewPager) { tab, position ->
  tab.text = tabTitles[position]
}.attach()

Код для использования этого TabLayoutMediator выглядит следующим образом: TabLayoutMediator(tabLayout, viewPager2) { tab, position -> viewPager2.setCurrentItem(tab.position, true) if (position == 1) tab.setText("Test2") if (position == 0) tab.setText("Test1") }.attach()

taranjeetsapra 13.04.2019 22:04

любой, кто читает это, должен дважды проверить версию библиотеки материалов своего приложения. TabLayoutMediator присутствует в implementation 'com.google.android.material:material:1.1.0-alpha08' , но студия Android по умолчанию импортировала для меня версию 1.0.0, в которой этого не было.

ansh sachdeva 24.08.2019 01:08

Как я могу установить точки на TabLayout (например, в карусели) вместо чисел на вкладках?

IgorGanapolsky 09.03.2020 22:17
viewPager.setCurrentItem(tab.position, true) не требуется и приводит к выбору 2-й вкладки и постоянному пролистыванию страниц!
ericn 15.05.2020 00:41

@ericn, ты прав, брат, установка текущего элемента выполняется автоматически.

Vikas Pandey 26.08.2020 20:36

@IgorGanapolsky Привет, вам просто нужно app:tabBackground = "@drawable/tab_selector", и вы tab_selector должны предоставить разные возможности рисования для выбранного и невыбранного случая

Vikas Pandey 26.08.2020 20:38

@anshsachdeva Я использую последнюю версию 1.3.0-alpha02, но не могу найти класс TablayoutMediator

Vikas Pandey 20.09.2020 20:02

@ericn, если удалить viewPager.setCurrentItem(tab.position, true), вкладки будут отображаться, но у нас не будет достаточного контроля над фрагментом (например, не будет фильтровать список в RecyclerView). Значит, надо добавить.

CoolMind 03.02.2021 12:56

Если вы вызываете этот метод из onCreateView, убедитесь, что viewPager != null или получите NPE.

CoolMind 03.02.2021 12:57

Забыл об этом attach() и потратил впустую 20 минут.

Rohaitas Tanoli 06.09.2021 18:41

Инициализируйте объект TabLayoutMediator с помощью объекта TabLayout, ViewPager2 , autoRefresh -- логического типа и объекта OnConfigurationChangeCallback.

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, true, new TabLayoutMediator.OnConfigureTabCallback() {
  @Override
  public void onConfigureTab(TabLayout.Tab tab, int position) {
    // position of the current tab and that tab  
  }
});

Наконец, просто вызовите attach() объект TabLayoutMediatorчтобы подключить tablayout к viewpager: -

 tabLayoutMediator.attach();

autoRefresh - ключ, если установлено значение true -- (по умолчанию установлено значение true )

RECREATES all the tabs of the tabLayout if notifyDataSetChanged is called to the viewpager adapter.

Используйте содержимое TabLayoutMediator.java

ОБНОВИТЬ

check this Create swipe views with tabs using ViewPager2

Вот обновленный ответ Как использовать TabLayout с ViewPager2 в Android

Теперь нам не нужно создавать класс из TabLayoutMediator

Использовать ниже dependencies

implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'

ОБРАЗЕЦ КОДА

XMl layout

<?xml version = "1.0" encoding = "utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android = "http://schemas.android.com/apk/res/android"
        xmlns:app = "http://schemas.android.com/apk/res-auto"
        xmlns:tools = "http://schemas.android.com/tools"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content"
            android:theme = "@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <androidx.appcompat.widget.Toolbar
                android:id = "@+id/toolbar"
                android:layout_width = "match_parent"
                android:layout_height = "?attr/actionBarSize"
                android:background = "?attr/colorPrimary"
                app:layout_scrollFlags = "scroll|enterAlways"
                app:popupTheme = "@style/ThemeOverlay.AppCompat.Light"/>

        <com.google.android.material.tabs.TabLayout
                android:id = "@+id/tabs"
                android:layout_width = "match_parent"
                android:layout_height = "wrap_content"/>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager2.widget.ViewPager2
            android:id = "@+id/viewpager"
            app:layout_anchor = "@id/tabs"
            app:layout_anchorGravity = "bottom"
            android:layout_width = "match_parent"
            android:layout_height = "match_parent"
    />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

Activity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.android.material.tabs.TabLayoutMediator

import com.google.android.material.tabs.TabLayout


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

//        setSupportActionBar(toolbar)
        viewpager.adapter = AppViewPagerAdapter(supportFragmentManager, lifecycle)

        TabLayoutMediator(tabs, viewpager, object : TabLayoutMediator.OnConfigureTabCallback {
            override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
                // Styling each tab here
                tab.text = "Tab $position"
            }
        }).attach()


    }
}

ОБНОВИТЬ

Если вы используете implementation 'com.google.android.material:material:1.1.0-alpha10', используйте код ниже

        TabLayoutMediator(tabs, viewpage,
        TabLayoutMediator.TabConfigurationStrategy { tab, position ->
            when (position) {
                0 -> { tab.text = "TAB ONE"}
                1 -> { tab.text = "TAB TWO"}
            }
        }).attach()

OUTPUT

любой, кто читает это, должен дважды проверить версию библиотеки материалов своего приложения. эта версия работала для меня, но студия Android по умолчанию импортировала версию 1.0.0, в которой этого не было

ansh sachdeva 16.08.2019 13:34

@anshsachdeva то же самое, я не могу найти класс TabLayoutMediator в com.google.android.material:material:1.0.0-alpha08, com.google.android.material:material:1.0.0-alpha09.

Seyid-Kanan Bagirov 23.08.2019 22:00

@Seyid-KananBagirov присутствует в реализации «com.google.android.material:material:1.1.0-alpha08» (обратите внимание на версию 1.1.0-alpha08, а не 1.0.0)

ansh sachdeva 24.08.2019 01:04

в 1.1.0-alpha10 они переименовали TabLayoutMediator.OnConfigureTabCallback в TabLayoutMediator.TabConfigurationStrategy

Almighty 08.09.2019 07:13

Я получаю неразрешенную ссылку для AppViewPagerAdapter?

crmepham 08.09.2019 12:40

@crmepham вам нужно создать AppViewPagerAdapter класс, подобный этому github.com/RathodNilesh14/TabLayout-with-viewpager2-/blob/…

AskNilesh 09.09.2019 06:56

@ Всемогущий, мне нужно просто переименовать его, и все?

android developer 19.09.2019 09:02

@androiddeveloper да, проверьте обновленный ответ

AskNilesh 19.09.2019 09:07

@NileshRathod Спасибо. Почему мы должны указывать TabConfigurationStrategy? Он помечен как ненулевой, но на самом деле мне не нужно ничего делать для обратного вызова. Для меня это пусто...

android developer 19.09.2019 10:07

также tabl;ayoutmediatar теперь не поддерживается, мы должны использовать какой-то другой метод для подключения tablayout и viewpager 2

Vikas Pandey 07.10.2020 08:49

В принятом ответе у нас также есть viewPager.setCurrentItem(tab.position, true). Это дает больше контроля над фрагментами.

CoolMind 03.02.2021 13:02

новый способ подключения viewpager2 и tablayout также решает проблему, из-за которой мы получим сбой, если все еще используем старый способ подключения viewpager2 и tablayout, когда я включил ProGuard

Franz Andel 26.05.2021 15:19

Вы можете использовать функцию расширения Kotlin:

fun TabLayout.setupWithViewPager(viewPager: ViewPager2, labels: List<String>) {

    if (labels.size != viewPager.adapter?.itemCount)
        throw Exception("The size of list and the tab count should be equal!")

    TabLayoutMediator(this, viewPager,
        TabLayoutMediator.TabConfigurationStrategy { tab, position ->
            tab.text = labels[position]
        }).attach()
}

И назовите это:

 tabLayout.setupWithViewPager(viewPager, listOf("Tab A", "Tab B"))

Какую зависимость мне нужно добавить, чтобы использовать это расширение?

Bartek Pacia 20.01.2020 15:22

Нет никакой зависимости, кроме Kotlin, чтобы использовать функции расширения :)

seyfullah.bilgin 20.01.2020 17:33

Да, знаю. Я имел в виду, какой артефакт Android KTX я должен добавить, чтобы использовать эту функцию расширения. Также у меня нет setupWithViewPager(ViewPager2, List) в наличии – у меня есть только setupWithViewPager(ViewPager)

Bartek Pacia 20.01.2020 19:11

Вы должны реализовать ViewPager2 (androidx.viewpager2:1.0.0) и компоненты matarial (com.google.android.material:material:1.2.0-alpha03) как артефакт, чтобы иметь возможность использовать эту функцию расширения.

seyfullah.bilgin 21.01.2020 10:16

И я также рекомендую использовать ViewPager2 вместо старого компонента ViewPager.

seyfullah.bilgin 21.01.2020 14:37

Да, у меня были включены эти артефакты, и эта функция расширения была недоступна. Я каким-то образом заработал, не используя эту функцию расширения. Спасибо, в любом случае.

Bartek Pacia 23.01.2020 12:46

Никаких хаков, никаких расширений, никакого TabLayoutMediator

Я нахожусь на implementation 'com.google.android.material:material:1.2.0-alpha02' и делаю следующее без, нуждающееся в TabLayoutMediator. Вместо этого я связываю TabLayout с ViewPager2, используя метод, описанный здесь. Я также добавил рабочий пример в github здесь. Я думаю, что свел решение к минимальному рабочему примеру. Я объясню важные моменты.

Добавление элементов в шаблон

Сначала нам нужно добавить в макет TabLayout и ViewPager2. Я поместил их здесь в LinearLayout и CoordinatorLayout, но вы, конечно, можете делать все, что захотите.

<!-- activity_main.xml -->
<?xml version = "1.0" encoding = "utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    tools:context = ".MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width = "match_parent"
        android:layout_height = "match_parent">

        <LinearLayout
            android:orientation = "vertical"
            android:layout_width = "match_parent"
            android:layout_height = "wrap_content">

            <com.google.android.material.tabs.TabLayout
                android:id = "@+id/tabLayout"
                android:layout_width = "match_parent"
                android:layout_height = "wrap_content"/>
            <androidx.viewpager2.widget.ViewPager2
                android:id = "@+id/pager"
                android:layout_width = "match_parent"
                android:layout_height = "wrap_content"/>

        </LinearLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Подключение адаптера к вьюпейджеру

Таким образом, адаптер отвечает за предоставление корректных фрагментов активности. Вам нужно будет расширить Фрагментстатеадаптер, что я сделал очень просто, как показано ниже (это частный класс, потому что он объявлен в моем MainActivity.java здесь):

    private class ViewStateAdapter extends FragmentStateAdapter {

        public ViewStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
            super(fragmentManager, lifecycle);
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            // Hardcoded in this order, you'll want to use lists and make sure the titles match
            if (position == 0) {
                return new BarFragment();
            }
            return new FooFragment();
        }

        @Override
        public int getItemCount() {
            // Hardcoded, use lists
            return 2;
        }
    }

Затем я могу подключить свой собственный адаптер к ViewPager, как показано ниже:

FragmentManager fm = getSupportFragmentManager();
ViewStateAdapter sa = new ViewStateAdapter(fm, getLifecycle());
final ViewPager2 pa = findViewById(R.id.pager);
pa.setAdapter(sa);

Я добавил фрагменты в свой viewpager. (Поскольку я жестко запрограммировал фрагменты в своем адаптере, вы должны использовать список и что-то вроде метода addFragment или что-то в этом роде)

TabLayout

Затем с

TabLayout tabLayout = findViewById(R.id.tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("Bar"));
tabLayout.addTab(tabLayout.newTab().setText("Foo"));

Я добавляю две вкладки в свой TabLayout, показывая заголовки, но пока не позволяя переключаться на фрагменты.

Подключение TabLayout к адаптеру

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                pa.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

Это должно быть довольно просто. Пользователь щелкает вкладку, я получаю позицию в своем обратном вызове и просто устанавливаю текущий элемент адаптера в эту позицию.

Изменить вкладку при свайпе

Наконец, мы возвращаемся назад, когда пользователь проводит пальцем по фрагменту, чтобы установить правильный элемент вкладки как выбранный.

pa.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
    @Override
    public void onPageSelected(int position) {
        tabLayout.selectTab(tabLayout.getTabAt(position));
    }
});

Хорошее решение! Работает как положено.

CoolMind 03.02.2021 11:19

Хорошая работа. Оцените проект на GitHub. Спасибо!

portsample 18.04.2021 16:07

Спасибо за ответ, не могли бы вы сказать мне, приведет ли перелистывание между вкладками к воссозданию фрагментов?

Kraken 21.09.2021 14:12

Я использую свою реализацию «com.google.android.material:material:1.2.1» и также не использовал tabLayoutMediator. Для начала https://developer.android.com/jetpack/androidx/migrate/class-mappings изменился для TabLayout в androidX, поэтому обязательно используйте com.google.android.material.tabs.TabLayout в своем операторе импорта. Вот остальная часть моей реализации решения: Объявление макета Xml для viewPager и TabLayout

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    android:background = "@color/tan_background"
    android:orientation = "vertical">

    <com.google.android.material.tabs.TabLayout
        android:id = "@+id/tabs"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"/>

    <androidx.viewpager2.widget.ViewPager2
        android:id = "@+id/viewpager"
        app:layout_anchor = "@id/tabs"
        app:layout_anchorGravity = "bottom"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"/>

</LinearLayout>

и файл активности

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set the content of the activity to use the activity_main.xml layout file
        setContentView(layout.activity_main);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);

        // Create an adapter that knows which fragment should be shown on each page
        SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(this,getSupportFragmentManager());

        // Set the adapter onto the view pager
        viewPager.setAdapter(adapter);

        // Find the tab layout that shows the tabs
        TabLayout tabLayout = findViewById(R.id.tabs);

        // Connect the tab layout with the view pager. This will
        //   1. Update the tab layout when the view pager is swiped
        //   2. Update the view pager when a tab is selected
        //   3. Set the tab layout's tab names with the view pager's adapter's titles
        //      by calling onPageTitle()
        tabLayout.setupWithViewPager(viewPager);
    }
}

Я также использовал настройку адаптера фрагмента в другом классе, где я передал контекст конструктору для разных вкладок.

Если название вашей вкладки происходит от string.xml.
Вы можете соединить fragment с title вместе в List, а затем установить заголовок с помощью TabLayoutMediator. Это поможет вам легко изменить порядок, удалить или добавить новый фрагмент

class MyFragment : Fragment() {

    override fun onCreateView(...): View? {
        ...

        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.text = pagerAdapter.getTabTitle(position)
        }.attach()
    }

    private inner class PagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
        val pages = listOf(
            Pair(HomeFragment.newInstance(), R.string.home),
            Pair(GraphFragment.newInstance(), R.string.graph),
            Pair(SettingFragment.newInstance(), R.string.setting),
        )

        override fun createFragment(position: Int): Fragment {
            return pages[position].first
        }

        override fun getItemCount(): Int {
            return pages.count()
        }

        fun getTabTitle(position: Int): String {
            return getString(pages[position].second)
        }
    }
}

Если вы программируете на JAVA. Вы можете использовать следующий адаптер для viewPager2:

public class ViewPagerAdapter extends FragmentStateAdapter {
  private static final int CARD_ITEM_SIZE = 10;
  public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
  }
  @NonNull @Override public Fragment createFragment(int position) {
    return CardFragment.newInstance(position);
  }
  @Override public int getItemCount() {
    return CARD_ITEM_SIZE;
  }
}

И в mainActivity вам нужно что-то встроенное со следующим:

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager = findViewById(R.id.view_pager);
    tabLayout = findViewById(R.id.tabs);
    viewPager.setAdapter(new ViewPagerAdapter(this));
    new TabLayoutMediator(tabLayout, viewPager,
        new TabLayoutMediator.TabConfigurationStrategy() {
          @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            tab.setText("Tab " + (position + 1));
          }
        }).attach();
  }
}

Спасибо за это! Я люблю случайные фрагменты кода без четкого указания, куда их поместить, так же, как и следующий парень, но этот ответ был для меня недостающей частью.

jawsware 23.06.2021 14:53

Ok. пока ты счастлив. Я счастлив. Что касается полного репетиторства, мы можем организовать класс. напишите мне сообщение!

Miguel Silva 23.06.2021 15:09

Убедитесь, что вы используете TabLayoutMediator after your set adapter to view_pager2

TabLayoutMediator(tab_layout, view_pager2) { tab, position ->
                tab.text = fragmentList[position].second  // here u can modify you text..
            }.attach()

это очень просто:

Java-код:

tabLayout=findViewById(R.id.tabLayout);
    viewPager=findViewById(R.id.viewPager);
    viewPager.setAdapter(new ViewPagerAdapter(this));

    new TabLayoutMediator(tabLayout, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
        @Override
        public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            if (position==0){
                tab.setText(R.string.photos);
                tab.view.setBackground(getResources().getDrawable(R.drawable.ic_rectangle_1345));
            }
            else {
                tab.setText(R.string.videos);
            }
        }
    }).attach();

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            tab.view.setBackground(getResources().getDrawable(R.drawable.ic_rectangle_1345));
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            tab.view.setBackgroundColor(Color.TRANSPARENT);
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

адаптер:

public class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
    super(fragmentActivity);
}

@NonNull
@Override
public Fragment createFragment(int position) {
    if (position==0) {
        return new PhotosFragment();
    }
    else {
        return new VideosFragment();
    }
}

@Override
public int getItemCount() {
    return 2;
}}

XML:

<com.google.android.material.tabs.TabLayout
    android:id = "@+id/tabLayout"
    android:layout_width = "match_parent"
    android:layout_height = "60dp"
    android:background = "@color/tool_bar_bg"
    app:layout_constraintEnd_toEndOf = "parent"
    app:layout_constraintStart_toStartOf = "parent"
    app:layout_constraintTop_toBottomOf = "@+id/collection_bar" />

<androidx.viewpager2.widget.ViewPager2
    android:id = "@+id/viewPager"
    android:layout_width = "match_parent"
    android:layout_height = "0dp"
    app:layout_constraintBottom_toBottomOf = "parent"
    app:layout_constraintEnd_toEndOf = "parent"
    app:layout_constraintStart_toStartOf = "parent"
    app:layout_constraintTop_toBottomOf = "@+id/tabLayout" />

Ваши макеты готовы, фрагменты готовы и адаптеры готовы. Все, что вам нужно сейчас, это настроить прослушиватель событий на

tabLayout.addOnTabSelectedListener(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) {

        }
    });

Это должно связать макет вкладки с вашим ViewPager2.

Другие вопросы по теме