Retain getChildFragmentManager navigation stack after removing and re-adding fragment

前端 未结 1 1429
忘掉有多难
忘掉有多难 2020-12-18 15:55

I have activity:

`
    

        
相关标签:
1条回答
  • 2020-12-18 16:39

    So that's how I solved this:

    MainActivity.xml

    <RelativeLayout>
        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </RelativeLayout>
    

    MainActivity.java

    public class MainActivity extends FragmentActivity {
    
        final FragmentContainer [] fragmentContainers = new FragmentContainer[3];
        int currentTabIndex = -1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            final FragmentMetaData [] fragmentContainersMetaData = {
                    new FragmentMetaData(FragmentA.class.getName(), null),
                    new FragmentMetaData(FragmentB.class.getName(), null),
                    new FragmentMetaData(FragmentC.class.getName(), null)
            };
    
            for (int i = 0; i < fragmentContainers.length; i++) {
                fragmentContainers[i] = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());
                fragmentContainers[i].addMetaData(fragmentContainersMetaData[i]);
            }
    
            tabPageNavigationSelection(0);
        }
    
        void replaceFragmentBy(final Fragment fragment) {
            FragmentManager fragmentManager = getSupportFragmentManager();                    
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.replace(R.id.container, fragment);
            fragmentTransaction.commitAllowingStateLoss();
        }
    
        // Method to switch between tabs
        void tabPageNavigationSelection (final int index) {
            if (currentTabIndex == index) {
                fragmentContainers[currentTabIndex].clearStackExceptRootFragment();
            } else {
                currentTabIndex = index;
                replaceFragmentBy(fragmentContainers[currentTabIndex]);
            }
        }
    }
    

    FragmentContainer.xml

    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:background="@color/lightest_gray"
        android:id="@+id/nestedContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    

    FragmentContainer.java

    public final class FragmentContainer extends Fragment {
        private final List<FragmentMetaData> fragmentMetaDataStack = new ArrayList<>();
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            initialize(inflater, container, R.layout.fragment_container);
    
            for (FragmentMetaData metaData : fragmentMetaDataStack) {
                showNestedFragment(Fragment.instantiate(getActivity(), metaData.className, metaData.fragmentBundle), fragmentMetaDataStack.indexOf(metaData) > 0, true);
            }
    
            return getFragmentView();
        }
    
        @Override
        public void onResume() {
            super.onResume();
            if (getChildFragmentManager().getFragments() == null){
                return;
            }
    
            int stackDepth = getChildFragmentManager().getFragments().size();
            if (stackDepth > 0 && fragmentMetaDataStack.size() < stackDepth &&
                    getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size() - 1) != null) {
                getChildFragmentManager().getFragments().get(fragmentMetaDataStack.size()-1).onResume();
            }
        }
    
        public void showNestedFragment(final Fragment fragment, final boolean addToBackStack, final boolean isRestoring) {
            final FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.nestedContainer, fragment);
            if (addToBackStack) {
                fragmentTransaction.addToBackStack(null);
            }
    
            if (!isRestoring) {
                fragmentMetaDataStack.add(new FragmentMetaData(fragment.getClass().getName(), fragment.getArguments()));
            }
    
            fragmentTransaction.commitAllowingStateLoss();
        }
    
        public void onBackPressed() {
            if (getChildFragmentManager().getBackStackEntryCount() > 0) {
                getChildFragmentManager().popBackStack();
                fragmentMetaDataStack.remove(fragmentMetaDataStack.size() - 1);
            } else {
                getActivity().finish();
            }
        }
    
        public void addMetaData(FragmentMetaData metaData) {
            fragmentMetaDataStack.add(metaData);
        }
    
        public void clearStackExceptRootFragment() {
            getChildFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            while (fragmentMetaDataStack.size() > 1) {
                fragmentMetaDataStack.remove(1);
            }
        }
    }
    

    Hopefully, it would help someone, who's trying to copy instagram navigation model :)

    0 讨论(0)
提交回复
热议问题