【问题标题】:Retain getChildFragmentManager navigation stack after removing and re-adding fragment删除和重新添加片段后保留 getChildFragmentManager 导航堆栈
【发布时间】:2015-02-06 13:53:29
【问题描述】:

我有活动:

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

在此容器内,根据按下的按钮显示 FragmentA 或 FragmentB。这些片段是嵌套子片段的容器。 IE。在每个片段中都包含自己的导航堆栈。

在 Activity 的 onCreate 中,我实例化了这两个片段:

fragmentA = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName()); fragmentB = (FragmentContainer) Fragment.instantiate(this, FragmentContainer.class.getName());

然后,我继续互相替换:

final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction() .replace(R.id.container, fragment); .commitAllowingStateLoss();

到目前为止,一切顺利,一切正常。但是

问题:

每次我用fragmentB替换fragmentA(反之亦然) - getChildFragmentManager() 破坏它的导航堆栈,fragmentA/B 每次都从头开始,而不是它在被替换之前包含的嵌套片段.

有什么想法吗?至少可行吗? 度过美好的一天, 康斯坦丁

【问题讨论】:

    标签: java android android-fragments android-support-library


    【解决方案1】:

    这就是我解决这个问题的方法:

    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);
            }
        }
    }
    

    希望它对试图复制 Instagram 导航模型的人有所帮助 :)

    【讨论】:

    • 如何使用嵌套的Fragments 中的showNestedFragment
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2020-05-07
    • 2018-11-04
    • 1970-01-01
    相关资源
    最近更新 更多