tfreifeld
tfreifeld

Reputation: 343

Selected tab in TabLayout is not shown on screen after returning to app

I am using ViewPager2 along with TabLayout and TabLayoutMediator to display some fragments. I have a problem when I leave the app (for example by tapping the home button) and then open it again, the TabLayout jumps to some other tabs. The correct tab, i.e. the last one the user was on when he left the app, is still selected and the correct fragment is still shown. It's just the tabs layout that gets scrolled to an unrelated position for some reason.

What can be the problem?

This is my code:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(UserItemsViewModel.class);

    viewPager = view.findViewById(R.id.view_pager);
    tabLayout = view.findViewById(R.id.tab_layout);

    viewPager.setAdapter(new ItemListFragmentAdapter(requireActivity(), mType));
    tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager,
            (tab, position) -> {
                if (position == 0) {
                    tab.setText("All");
                } else {
                    tab.setText(((ItemListFragmentAdapter) viewPager.getAdapter()).getItemAt(position - 1).getName());
                }
            }
    );

    mViewModel.getFormatsLD().observe(getViewLifecycleOwner(), new Observer<List<FormatItem>>() {
        @Override
        public void onChanged(List<FormatItem> formatItems) {
            ItemListFragmentAdapter adapter = (ItemListFragmentAdapter) viewPager.getAdapter();
            if (adapter != null) {
                ((ItemListFragmentAdapter) viewPager.getAdapter()).setItems(formatItems);
                adapter.notifyDataSetChanged();

            }
        }
    });
}

@Override
public void onResume() {
    super.onResume();
    tabLayoutMediator.attach();
    viewPager.setCurrentItem(currentPage, false);


}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
    tabLayoutMediator.detach();
}

currentPage is a field in the parent fragment which hosts the ViewPager2 and TabLayout which is used to retain the last tab/page the user was on when the fragment got paused.

You can see in these photos below how it looks before leaving the app and after returning to it:

enter image description here

enter image description here

Upvotes: 1

Views: 1245

Answers (1)

Ali
Ali

Reputation: 529

Remove .detach() and .attach() from on pause and move .attach() to onCreateView()

@Override
public void onResume() {
    super.onResume();
    viewPager.setCurrentItem(currentPage, false);
}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
}

it's not necessary because garbage collection automatedly does so, but itconsidered as best practice

@Override
public void onDestroy() {
    super.onDestroy();
    tabLayoutMediator.detach();
}

Upvotes: 1

Related Questions