Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment no longer exists for key FragmentStateAdapter with Viewpager2

I am using ViewPager2 for my project. I need to use nested fragments inside a fragment with viewpager2. it works like charm until I try to navigate between fragments(not nested ones).

After the first time navigating between fragments, the application crash with the error explained below.

the fragment which contains nested fragments OnCreateView method:

View view = inflater.inflate(R.layout.orders_fragment, null);

ViewPager2 viewPager = view.findViewById(R.id.childViewPager);

TabLayout tabs = view.findViewById(R.id.tabs);

SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager(),getLifecycle());

viewPager.setAdapter(sectionsPagerAdapter);

TabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy = (tab, position) -> {

    String[] order_activity_tabs = getResources().getStringArray(R.array.situations);

    for (int i=0; i<order_activity_tabs.length; i++) {

        if(i==position)
            tab.setText(order_activity_tabs[i]);

    }
};

TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabs, viewPager, tabConfigurationStrategy);
tabLayoutMediator.attach();

return view;

When I return the fragment that contains nested fragments it crashes with

 java.lang.IllegalStateException: Fragment no longer exists for key f#0: unique id 4fbe17b8-5e22-4e07-a543-4a79445ad39c
        at androidx.fragment.app.FragmentManagerImpl.getFragment(FragmentManagerImpl.java:365)
        at androidx.viewpager2.adapter.FragmentStateAdapter.restoreState(FragmentStateAdapter.java:549)
        at androidx.viewpager2.widget.ViewPager2.restorePendingState(ViewPager2.java:350)
        at androidx.viewpager2.widget.ViewPager2.dispatchRestoreInstanceState(ViewPager2.java:375)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:4045)
        at android.view.View.restoreHierarchyState(View.java:20253)
        at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:548)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:907)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)

There are solutions for FragmentStatePagerAdapter but there is no for FragmentStateAdapter. And because I can't override methods in FragmentStateAdapter, implementing this solutions are impossible.

Thank you for reading this. Any help is appreciated.

like image 230
Eren Tüfekçi Avatar asked Dec 26 '19 09:12

Eren Tüfekçi


1 Answers

Using viewpager2 with FragmentStateAdapter has a similar behaviour than FragmentStatePagerAdapter

Actually there are two ways of solving this problem

First one is seting setSaveEnabled() to false into our viewpager2

viewpager2.setSaveEnabled(false)

The other one is overriding restoreState at our adapter and return null

Check : https://developer.android.com/reference/androidx/viewpager2/adapter/FragmentStateAdapter

like image 163
Gastón Saillén Avatar answered Sep 28 '22 09:09

Gastón Saillén