简体   繁体   English

从bottomNavigationView导航到片段B时保存片段A的状态

[英]Save state of fragment A when navigating from bottomNavigationView to fragment B

I am new to Android and I have been struggling for some time now with saving state of a fragment.我是 Android 新手,我一直在努力保存片段状态。 My app has 5 options in the bottomNavigationView (I am using the default activity from Android).我的应用程序在 bottomNavigationView 中有 5 个选项(我使用的是 Android 的默认活动)。 In fragment A (actually called "SearchFragment") I have a button and when clicked it sets some text in a TextBox.在片段 A(实际上称为“SearchFragment”)中,我有一个按钮,单击它会在 TextBox 中设置一些文本。 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).我想在导航到另一个片段并返回到片段 A 时保存此片段的状态(带有文本)(并且在上一次单击按钮时仍保留文本)。

From the code I wrote it saves the fragment's state when changing orientation for example, but doesn't do so when navigating to other fragments and then coming back.例如,从我编写的代码中,它会在更改方向时保存片段的状态,但在导航到其他片段然后返回时则不会这样做。

How could I change the code?我怎么能改变代码? Or is there any other method to save the current state of a fragment on navigation?或者有没有其他方法可以保存导航片段的当前状态? I really need some help here...and thanks for your attention!我真的需要一些帮助……感谢您的关注!

My mainActivity looks like this:我的 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);
        }

    }

And the fragment class looks like this:片段类如下所示:


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

Few facts around Android Navigation Component with Bottom Navigation Bar.关于带有底部导航栏的 Android 导航组件的一些事实。

- > Fragments are always recreated (onCreate, onViewCreated, onViewDestroyed are called as soon as the user navigates to another fragment) - > 片段总是重新创建(只要用户导航到另一个片段,就会调用 onCreate、onViewCreated、onViewDestroyed)

- > Fragment will save its state only when activity is recreated (eg screen rotation) , navigating between fragments doesn't save fragment's state. - > Fragment 仅在重新创建活动(例如屏幕旋转)时才会保存其状态,在 Fragment 之间导航不会保存 Fragment 的状态。

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).我想在导航到另一个片段并返回到片段 A 时保存此片段的状态(带有文本)(并且在上一次单击按钮时仍保留文本)。

This wont be possible as a new instance of FragmentA is created when you navigate back from fragmentB to Fragment A.这是不可能的,因为当您从 fragmentB 导航回 Fragment A 时,会创建 FragmentA 的新实例。

you can not achieve this with navigation controller as of now.到目前为止,您无法使用导航控制器实现此目的。

Since you are using navigation component , You should switch to using Viewmodel to solve retain fragment state issue.由于您使用的是导航组件,您应该切换到使用Viewmodel来解决保留片段状态问题。

Consult the following link to see how to communicate and save data between fragments using viewmodel.请参阅以下链接以了解如何使用视图模型在片段之间进行通信和保存数据。

https://androidwave.com/fragment-communication-using-viewmodel/ https://androidwave.com/fragment-communication-using-viewmodel/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM