android - BottomNavigationView + 在导航到不同选项卡时保存片段状态
问题描述
我正在使用BottomNavigationView
底部标签。
1) 选项卡 1 - 从服务器获取数据并显示到RecyclerView
2) 选项卡 2 - 从服务器获取 URL 并加载Webview
3) 选项卡 3 - 从服务器获取数据并显示到RecyclerView
4) 选项卡 4 - 使用设置屏幕PreferenceFragmentCompat
为了在用户切换选项卡时保存这些片段的状态,我正在使用此博客中的以下代码
保存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 个项目并在导航到其他片段后再次返回设置屏幕,我会在顶部看到第 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();
}
解决方案
你现在正在做的是用这段代码替换片段
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container_fragment, fragment, tag)
.commit();
虽然您可以添加片段而不是像这段代码那样替换它们
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container_fragment, fragment, tag)
.commit();
这将做的是添加片段而不是替换它,因此片段状态将被保存。
推荐阅读
- c++ - 在 Clang 中的两个源位置之间复制源代码
- c++ - 将矩阵附加到 stl 矩阵(2d std::vector)
- c# - Richtextbox 多种背景颜色
- python - 如何通过 Shiny 中的 R 在 Python 文件中运行特定函数?
- rust - 有没有办法直接消耗一条人造丝链而不先收集它?
- winapi - 在进程运行时调整令牌信息
- python - 我关于 Sqrt(x) 的解决方案有什么问题
- google-apps-script - 谷歌表格 - 复制行脚本复制整个工作表
- velocity - 速度变量(同时使用字符串和整数变量)
- delphi - 在 Delphi 中的表单之间切换