从bottomNavigationView导航到片段B时保存片段A的状态
Posted
技术标签:
【中文标题】从bottomNavigationView导航到片段B时保存片段A的状态【英文标题】:Save state of fragment A when navigating from bottomNavigationView to fragment B 【发布时间】:2020-07-07 13:47:32 【问题描述】:我是 android 新手,我一直在努力保存片段的状态。 我的应用在底部导航视图中有 5 个选项(我使用的是 Android 的默认活动)。在片段 A(实际上称为“SearchFragment”)中,我有一个按钮,当单击它时,它会在 TextBox 中设置一些文本。我想在导航到另一个片段并返回片段 A 时保存该片段的状态(其中包含文本)。
根据我编写的代码它会在改变方向时保存片段的状态,但在导航到其他片段然后返回时不会这样做。
如何更改代码?或者有没有其他方法可以保存导航片段的当前状态?我真的需要一些帮助...感谢您的关注!
我的 mainActivity 如下所示:
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_search, R.id.navigation_explore, R.id.navigation_trips, R.id.navigation_groups,R.id.navigation_profile)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
片段类如下所示:
public class SearchFragment extends Fragment
private SearchViewModel searchViewModel;
Button b;
TextView text;
Bundle savedState = null;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState)
View root = inflater.inflate(R.layout.fragment_search, container, false);
searchViewModel = ViewModelProviders.of(this).get(SearchViewModel.class);
final TextView textView = root.findViewById(R.id.text_dashboard);
searchViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>()
@Override
public void onChanged(@Nullable String s)
textView.setText(s);
);
Log.i("state","onCreate");
Log.i("bundleIsNull", "" + (savedState == null));
b = root.findViewById(R.id.button2);
text = root.findViewById(R.id.textView);
b.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
text.setText("YEEEY");
Log.i("bundleIsNull", "" + (savedState == null));
);
if(savedInstanceState != null && savedState == null)
savedState = savedInstanceState.getBundle("buttonText");
if(savedState != null)
text.setText(savedState.getCharSequence("buttonText"));
savedState = null;
return root;
@Override
public void onDestroyView()
super.onDestroyView();
Log.i("state", "onDestroyView");
savedState = saveState();
text = null;
b = null;
private Bundle saveState()
Bundle state = new Bundle();
state.putCharSequence("buttonText", text.getText());
return state;
@Override
public void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
Log.i("state", "onSaveInstanceState");
outState.putBundle("buttonText", (savedState != null)? savedState : saveState());
@Override
public void onPause()
super.onPause();
Log.i("state","onPause");
【问题讨论】:
查看这个创建自定义导航器的解决方案。 ***.com/a/51684125/10300202 【参考方案1】:关于带有底部导航栏的 Android 导航组件的一些事实。
-> 片段总是被重新创建(一旦用户导航到另一个片段,就会调用 onCreate、onViewCreated、onViewDestroyed)
-> Fragment 只会在 Activity 重新创建时保存其状态(例如屏幕旋转),在 Fragment 之间导航不会保存 Fragment 的状态。
我想保存这个片段的状态(那里有文字) 导航到另一个片段并返回片段 A (并保留上一次单击按钮后的文本)。
这是不可能的,因为在创建 FragmentA 的新实例时 您从 fragmentB 导航回 Fragment A。
到目前为止,您无法使用导航控制器实现此目的。
由于您使用的是导航组件,您应该切换到使用Viewmodel来解决保留片段状态的问题。
请参阅以下链接,了解如何使用视图模型在 Fragment 之间进行通信和保存数据。
https://androidwave.com/fragment-communication-using-viewmodel/
【讨论】:
感谢您的帮助!!它工作了 :) 我为所有片段添加了一个 sharedViewModel,现在它可以工作了 嘿@Kate 你能分享一下你是如何在 github 上做的吗?谢谢! 有一个视频模型用于此目的,有没有一种方法可以让我们使用scrollToPosition
和 recycler view
。由于视图模型保留了最新的拉取数据并且已恢复。我们总是可以将数据附加到适配器,并在更改viewmodel
中的片段更新列表并在恢复时,在适配器中重新发布,但这总是滚动到顶部但不是最后保存的 ui 位置,scrollToPosition
也不起作用。有什么想法吗?以上是关于从bottomNavigationView导航到片段B时保存片段A的状态的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 material.BottomNavigationView 设置 Jetpack 导航
导航组件 - BottomNavigationView - 返回时不要保留 startDestination 片段
使用导航组件时从 BottomNavigationView 中移除 Badge
Android ------ Android X 的BottomNavigationView底部导航栏