13

I have a simple setup using ViewPager2 and TabLayout with preset TabItems:

...

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="0dp"
            android:layout_height="64dp"
            app:tabTextColor="@color/c0696D7"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/palettesToggle"
            app:layout_constraintTop_toTopOf="parent"
            app:tabBackground="@color/cEEEEEE"
            app:tabIndicatorColor="@color/cFFFFFF"
            app:tabGravity="fill"
            app:tabUnboundedRipple="true"
            app:tabIconTint="@color/palettes_icon_tint"
            app:tabIndicatorGravity="stretch"
            app:tabMode="fixed">

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_layers" />

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_view" />

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_properties" />

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_blocks" />

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_blocks" />

            <com.google.android.material.tabs.TabItem android:icon="@drawable/palettes_settings" />

        </com.google.android.material.tabs.TabLayout>

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

...

and the following wiring code:

TabLayoutMediator(tabs, viewPager) { tab, position ->

        }.attach()

The following setup ignores the TabItem icon attribute, and I see empty tabs. It seems that TabLayoutMediator completely overrides the defined xml attributes and i must reset those attributes as part of the TabConfigurationStrategy callback. Am I missing something?

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
Evgeni Roitburg
  • 1,958
  • 21
  • 33
  • have a look at this issue thanks :) https://stackoverflow.com/questions/66474349/tablayoutmediator-not-showing-custom-tabitem – Atif AbbAsi Mar 04 '21 at 12:11

1 Answers1

15

The method TabLayoutMediator.attach() calls the method tabLayout.removeAllTabs(); which removes all tabs and then adds tabs again.

Check also the official doc:

When creating an instance of this class, you must supply an implementation of TabLayoutMediator.TabConfigurationStrategy in which you set the text of the tab, and/or perform any styling of the tabs that you require.

Something like:

new TabLayoutMediator(tabs, viewpager, new TabLayoutMediator.TabConfigurationStrategy() {
      @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
        //Configure your tabs...
        tab.setText(...);
        tab.setIcon(...);
      }
    }).attach();

or:

 TabLayoutMediator(tabs, viewpager,
    TabLayoutMediator.TabConfigurationStrategy { tab, position ->
        //Configure tabs..
        when (position) {
            0 -> { tab.text = "..."}
            1 -> { tab.text = "..."}
        }
    }).attach()
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • 4
    Thanks for the detailed explanation, I'm actually asking if there is a way to preserve the default xml styling? as I would expect... – Evgeni Roitburg Nov 27 '19 at 07:45
  • 1
    @EvgeniRoitburg I don't think. Also the `tabLayout.setupWithViewPager()` (old viewpager) removes all the tabs reading the data from the adapter. – Gabriele Mariotti Nov 27 '19 at 07:51
  • 4
    So any configuration applied to the tabs in XML has to be specified once again programmatically? This is a violation of DRY. – Soyal7 May 16 '20 at 14:53
  • 2
    This approach forces to code markup instead of using xml, weird implementation – XZen Mar 06 '21 at 13:48
  • Calling second attach on the same TabLayoutMediator will throw -> IllegalStateException("TabLayoutMediator is already attached"); For anyone wondering why do you need to call detach first. – Beemo Mar 09 '22 at 21:28