TabLayout indicator didn't change position when click tab

Issue

In my another fragment has similar TabLayout and ViewPager2 architecture, but that fragment’s TabLayout work normally.
This problem only occur when click tab, but swipe page at ViewPager2 the indicator work fine, and if I click tab then swipe to other page the indicator will work fine too.
Is there any wrong with my code?

TabLayout and ViewPager2 in xml:

<com.google.android.material.tabs.TabLayout
        android:id="@+id/mTabLayout"
        style="@style/MyTabStyle2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/light_gray_1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tabGravity="fill"
        tools:ignore="SpeakableTextPresentCheck"
        tools:layout_height="50dp">
    </com.google.android.material.tabs.TabLayout>


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/mViewPager"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/light_gray_1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mTabLayout" />

here is fragment which put TabLayout and ViewPager2:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initAdapter();
    initViewPager();
    initTabLayout();
}
private void initAdapter() {
    titlesList.add(getString(R.string.message_tab_multi));
    titlesList.add(getString(R.string.message_tab_single));
    titlesList.add(getString(R.string.message_tab_welcome));
    productPagerAdapter = new MessagePager2Adapter(this);
}

public void initViewPager() {
    mViewPager.setAdapter(productPagerAdapter);
    mViewPager.setOffscreenPageLimit(titlesList.size());
}

public void initTabLayout() {
    new TabLayoutMediator(mTabLayout, mViewPager, (tab, position) ->
            tab.setText(titlesList.get(position))).attach();
}

private class MessagePager2Adapter extends FragmentStateAdapter {

    public MessagePager2Adapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public MessagePager2Adapter(@NonNull Fragment fragment) {
        super(fragment);
    }

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

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            default:
            case TAB_MESSAGE_MULTI:
                return MessagePostMultiFragment.newInstance();
            case TAB_MESSAGE_SINGLE:
                return MessagePostSingleFragment.newInstance();
            case TAB_MESSAGE_WELCOME:
                return MessagePostWelcomeFragment.newInstance();
        }
    }

    @Override
    public int getItemCount() {
        return titlesList.size();
    }
}

Problem image and video:
Click tab at position 1(click position 1 but indicator still at position 0)
video

Below is another fragment architecture:

TabLayout and ViewPager2 in xml:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/mTabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    style="@style/MyTabStyle"
    app:tabGravity="fill"
    android:background="@color/light_gray_2"
    tools:layout_height="50dp"/>

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/mViewPager"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/light_gray_1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/mTabLayout" />

fragment which put TabLayout and ViewPager2:

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initAdapter();
    initViewPager();
    initTabLayout();

}

private void initAdapter() {
    titlesList.add(getString(R.string.product_tab_product_search));
    titlesList.add(getString(R.string.product_tab_product_serving));
    pagerAdapter = new ProductPagerAdapter(this);
}

public void initViewPager() {
    mViewPager.setAdapter(pagerAdapter);
    mViewPager.setOffscreenPageLimit(titlesList.size());
}

public void initTabLayout() {
    new TabLayoutMediator(mTabLayout, mViewPager, (tab, position) ->
            tab.setText(titlesList.get(position))).attach();

}

public class ProductPagerAdapter extends FragmentStateAdapter {

    public ProductPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public ProductPagerAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

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

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            case TAB_PRODUCT_SEARCH:
                return ProductSearchFragment.newInstance();
            case TAB_PRODUCT_SERVING:
                return ProductServingFragment.newInstance();
            default:
                return ProductSearchFragment.newInstance();
        }
    }

    @Override
    public int getItemCount() {
        return titlesList.size();
    }
}

Update:
My each fragment in ViewPager2 has recyclerView, and this situation only occur when recyclerView has item, if I set adapter getItemCount return 0, then the indicator work correctly, but return 1 or more, indicator will broken, even my TabLayout not attach with ViewPager2.

Solution

I solve this problem by set TabLayout IndicatorAnimationDuration 0, but i dont know the exactly problem with. Can someone explain for me? thanks.

Answered By – Jeff Lin

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published