BottomNavigationView +导航到其他选项卡时保存片段状态

时间:2019-11-01 07:13:25

标签: android android-fragments bottomnavigationview android-design-library

我将BottomNavigationView用于底部的标签。

1)标签1-从服务器获取数据并显示到RecyclerView
2)标签2-从服务器获取URL并加载Webview
3)标签3-从服务器获取数据并显示到RecyclerView
4)标签4-使用PreferenceFragmentCompat

设置屏幕

为了在用户切换选项卡时保存这些片段的状态,我正在使用此blog

中的以下代码

Fragment.SavedState保存到SparseArray<Fragment.SavedState>

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

当用户导航回到上一个标签时,再次恢复状态

fragment.setInitialSavedState(savedState)

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

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

但是,前三个选项卡再次进行Web服务调用,并且一切都重新加载。另外,我看到Bundle savedInstanceState方法的onCreateView参数对于前三个选项卡也不为空。

我的问题是

1)PreferenceFragmentCompat(第四个标签)如何自动恢复状态?
2)如何在前三个选项卡中使用非空的Bundle savedInstanceStateonCreateView方法的参数),并像第四个选项卡那样恢复状态?
3)为什么前三个标签不能自动恢复状态?

编辑

我使用的是与blog相同的代码。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

此操作将添加片段而不是替换片段,因此将保存片段状态。

答案 1 :(得分:0)

尝试以onCreate方法移动前3个片段的获取操作。

这样做的原因是,当您再次输入片段时,将调用onActivityCreated并再次获取数据,然后更新recyclerview,该重置将重置并将您移回recyclerview的起点。

但是,如果您将其命名为onCreate,则只有在您第一次输入片段时才进行数据获取,因此它不会更新recyclerview,也不会重置它。