Home > OS >  Issue with tablayout, on switching to the second tab it will jump back to the first tab
Issue with tablayout, on switching to the second tab it will jump back to the first tab

Time:07-26

I am trying to create a tab layout for my program. There are two tabs. If I try to switch to Tab2 instead of staying on Tab2, it changes back to Tab1. I have 0 clue what is causing this problem.

Here is my code

MainActivity:

tabLayout = findViewById(R.id.tablayout);
    viewPager2 = findViewById(R.id.viewpager);

    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentAdapter = new CustomAdapter(fragmentManager, getLifecycle());

    viewPager2.setAdapter(fragmentAdapter);
    tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
    tabLayout.addTab(tabLayout.newTab().setText("Tab2"));

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

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

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

    viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageScrollStateChanged(int state) {

            tabLayout.selectTab(tabLayout.getTabAt(state));
        }
    });

CustomAdapter:

public class CustomAdapter extends FragmentStateAdapter {

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

@NonNull
@Override
public Fragment createFragment(int position) {
    if(position == 1) return new BlankFragment1();
    return new BlankFragment2();
}

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

CodePudding user response:

Following the official docs here you can use a TabLayoutMediator to link the tab layout and pager instead of doing it with your own listeners.

However, the root of the problem you observed is that state in onPageScrollStateChanged is not the position that it scrolled to - it is an integer representing the scroll state. Since SCROLL_STATE_IDLE is 0, and SCROLL_STATE_DRAGGING is 1, as soon as you stopped dragging it would snap back to tab 0.

Using TabLayoutMediator (recommended)

To use the TabLayoutMediator replace your addOnTabSelectedListener, registerOnPageChangeCallback, and manually setting the tabs (addTab) with this, which links the tabs to the view pager and provides a method to set the tab titles

// remove the "addTab" calls, "addOnTabSelectedListener", 
// and "registerOnPageChangeCallback"

new TabLayoutMediator(tabLayout, viewPager2,
        (tab, position) -> tab.setText("Tab"   (position   1))
).attach();

Using your own listeners

It is still possible to use your own listeners, but you have to change the view pager listener to use onPageSelected instead of onPageScrollStateChanged, like this:

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

Note: The positions are 0-based, so you are showing "BlankFragment2" in position 0 and "BlankFragment1" in position 1 (not sure if that is what you intended).

  • Related