从 bottomNavigationView 导航到片段 B 时保存片段 A 的状态
Save state of fragment A when navigating from bottomNavigationView to fragment B
我是 Android 的新手,一段时间以来我一直在努力保存片段状态。
我的应用程序在 bottomNavigationView 中有 5 个选项(我使用 Android 中的默认 activity)。在片段 A(实际上称为 "SearchFragment")中,我有一个按钮,当单击它时,它会在文本框中设置一些文本。我想在导航到另一个片段并返回到片段 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);
}
}
片段 class 看起来像这样:
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");
}
}
关于 Android 带有底部导航栏的导航组件的一些事实。
-> 总是重新创建片段(一旦用户导航到另一个片段,就会调用 onCreate、onViewCreated、onViewDestroyed)
- >片段将仅在重新创建activity时保存其状态(例如屏幕旋转),在片段之间导航不会保存片段的状态。
I want to save the state of this fragment (with the text there) when
navigating to another fragment and the coming back to the fragment A
(and have the text still there from the previous button click).
这是不可能的,因为当创建 FragmentA 的新实例时
您从 fragmentB 导航回 Fragment A。
您目前无法使用导航控制器实现此目的。
由于您使用的是导航组件,您应该改用Viewmodel来解决保留片段状态的问题。
参考以下内容link了解如何使用视图模型在片段之间通信和保存数据。
https://androidwave.com/fragment-communication-using-viewmodel/
我是 Android 的新手,一段时间以来我一直在努力保存片段状态。 我的应用程序在 bottomNavigationView 中有 5 个选项(我使用 Android 中的默认 activity)。在片段 A(实际上称为 "SearchFragment")中,我有一个按钮,当单击它时,它会在文本框中设置一些文本。我想在导航到另一个片段并返回到片段 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);
}
}
片段 class 看起来像这样:
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");
}
}
关于 Android 带有底部导航栏的导航组件的一些事实。
-> 总是重新创建片段(一旦用户导航到另一个片段,就会调用 onCreate、onViewCreated、onViewDestroyed)
- >片段将仅在重新创建activity时保存其状态(例如屏幕旋转),在片段之间导航不会保存片段的状态。
I want to save the state of this fragment (with the text there) when navigating to another fragment and the coming back to the fragment A (and have the text still there from the previous button click).
这是不可能的,因为当创建 FragmentA 的新实例时 您从 fragmentB 导航回 Fragment A。
您目前无法使用导航控制器实现此目的。
由于您使用的是导航组件,您应该改用Viewmodel来解决保留片段状态的问题。
参考以下内容link了解如何使用视图模型在片段之间通信和保存数据。
https://androidwave.com/fragment-communication-using-viewmodel/