首页 > 解决方案 > BottomNavigationView + 在导航到不同选项卡时保存片段状态

问题描述

我正在使用BottomNavigationView底部标签。

1) 选项卡 1 - 从服务器获取数据并显示到RecyclerView
2) 选项卡 2 - 从服务器获取 URL 并加载Webview
3) 选项卡 3 - 从服务器获取数据并显示到RecyclerView
4) 选项卡 4 - 使用设置屏幕PreferenceFragmentCompat

为了在用户切换选项卡时保存这些片段的状态,我正在使用此博客中的以下代码

保存Fragment.SavedStateSparseArray<Fragment.SavedState>

Fragment.State currentFragmentState = getSupportFragmentManager().saveFragmentInstanceState(currentFragment)

当用户导航回以前的选项卡时再次恢复状态

fragment.setInitialSavedState(savedState)

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.container_fragment, fragment, tag)
        .commit();

我所看到的是只有选项卡 4(带有 的设置屏幕PreferenceFragmentCompat)保持状态 - 如果我向下滚动到第 10 个项目并在导航到其他片段后再次返回设置屏幕,我会在顶部看到第 10 个位置。

但是,前三个选项卡再次调用 Web 服务并重新加载所有内容。另外,我可以看到前三个选项卡Bundle savedInstanceState的方法参数onCreateView也不为空。

我的问题是

1)(第4个选项卡)如何PreferenceFragmentCompat自动恢复状态?
2)如何在前三个选项卡中使用非空Bundle savedInstanceState(方法的参数)并像第四个选项卡一样恢复状态? 3)为什么前三个选项卡不会自动恢复状态?onCreateView

编辑

我使用与博客相同的代码。

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

                switch (item.getItemId()) {

                    case R.id.navigation_item_1:                       
                        swapFragments(new Fragment1(), item.getItemId(), TAG_1);
                        return true;

                    case R.id.navigation_item_2:      
                        swapFragments(new Fragment2(), item.getItemId(), TAG_2);
                        return true;

                    case R.id.navigation_item_3:
                        swapFragments(new Fragment3(), item.getItemId(), TAG_3);
                        return true;

                    case R.id.navigation_item_4:
                        swapFragments(new Fragment4(), item.getItemId(), TAG_4);
                        return true;

                    default:
                        return false;
                }
            }
        });

        private void swapFragments(Fragment fragment, int itemId, String tag) {
            if (getSupportFragmentManager().findFragmentByTag(tag) == null) {
                saveFragmentState(itemId, tag);
                createFragment(fragment, itemId, tag);
            }
        }

        private void saveFragmentState(int itemId, String tag) {
            Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container_fragment);
            if (currentFragment != null) {
                fragmentStateArray.put(currentSelectedItemId, getSupportFragmentManager().saveFragmentInstanceState(currentFragment));
            }

            currentSelectedItemId = itemId;
        }

        private void createFragment(Fragment fragment, int itemId, String tag) {
            fragment.setInitialSavedState(fragmentStateArray.get(itemId));

            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.container_fragment, fragment, tag)
                    .commit();
        }

标签: androidandroid-fragmentsbottomnavigationviewandroid-design-library

解决方案


你现在正在做的是用这段代码替换片段

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.container_fragment, fragment, tag)
        .commit();

虽然您可以添加片段而不是像这段代码那样替换它们

getSupportFragmentManager()
        .beginTransaction()
        .add(R.id.container_fragment, fragment, tag)
        .commit();

这将做的是添加片段而不是替换它,因此片段状态将被保存。


推荐阅读