如何在 SpaceNavigationView 中保存 Fragment 的状态

How to save state of Fragment in a SpaceNavigationView

我已经对此进行了搜索,但一无所获,这有助于我解决问题。在我的代码中,我有一个带有五个片段的 SpaceNavigationView(如 BottomNavigationView)。

所以在片段 A 中,我放了一个 Recyclerview。如果 Recyclerview 的一个项目被点击,它将用一个新的子片段 B 替换当前片段。

在 Fragment B 中,我设置了一个 Chronometer,它应该在按下时计算时间。 现在,如果我从 Fragment B 切换到 Fragment C,然后返回到 Fragment B,Chronometer 将从零开始,因为该片段已被替换。

我尝试过使用onSaveInstanceState,以便在重新创建Fragment时调用它,但这对我不起作用。

这是主页Activity 的一部分,其中包括所有片段。

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        init();
        setFragment(fragmentHome);


        navigationView.initWithSaveInstanceState(savedInstanceState);
        navigationView.addSpaceItem(new SpaceItem("", R.drawable.bottom_baby));
        navigationView.addSpaceItem(new SpaceItem("", R.drawable.bottom_advise));
        navigationView.addSpaceItem(new SpaceItem("", R.drawable.ic_favorite_black_24dp));
        navigationView.addSpaceItem(new SpaceItem("", R.drawable.ic_settings));


        navigationView.setSpaceOnClickListener(new SpaceOnClickListener() {
            @Override
            public void onCentreButtonClick() {
                setFragment(fragmentPlayground);
                navigationView.setCentreButtonSelectable(true);
            }

            @Override
            public void onItemClick(int itemIndex, String itemName) {
                switch (itemIndex) {
                    case 0:
                        setFragment(fragmentHome);
                        return;
                    case 1:
                        setFragment(fragmentAdvising);
                        return;
                    case 2:
                        setFragment(fragmentMemories);
                        return;
                    case 3:
                        setFragment(fragmentSettings);
                        return;
                    default:
                        setFragment(fragmentHome);
                        return;

                }
            }

            @Override
            public void onItemReselected(int itemIndex, String itemName) {
                Toast.makeText(HomeActivity.this, itemIndex + " " + itemName, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void setFragment(Fragment fragment) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.container, fragment);
        fragmentTransaction.commit();
    }

因此,如果我现在导航到 FragmentHome 并使用 Reycleritems 的 OnClickListener,我将切换到 Fragment_Chronograph

 @Override
    public void onItemClick(int position) {
        switch (position) {
            case 0:
                getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment_chronograph).commit();
        }

所以现在我在 Fragment_Chronograph 并且想为 Chronograph 保留基础。我会将变量保存在 onSavedInstanceState 中,它会在 Activity 暂停时调用。

 @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        startTime = SystemClock.elapsedRealtime() - chronometerLeft.getBase();
        outState.putLong(CHRONOLEFT_TIME_SAVE_ID,startTime);
        super.onSaveInstanceState(outState);

    @Override
    public void onPause() {
        super.onPause();
        onSaveInstanceState(new Bundle());
    }

最后,我在 OnCreate 方法中放入了这段用于恢复的代码:

if (savedInstanceState != null) {
            startTime = savedInstanceState.getLong(CHRONOLEFT_TIME_SAVE_ID,0);
            chronometerLeft.setBase(startTime - SystemClock.elapsedRealtime());
            chronometerLeft.start();

OnSaveInstanceState 被调用,但在 OnCreate 方法中不会被调用。如果有人能帮助我解决这个问题,我将不胜感激。我正在寻找几天,但没有得到解决方案。

@阿文

FragmentHome在init()方法中启动;

private void init() {

        navigationView = findViewById(R.id.space);

        fragmentHome = new FragmentHome();
        fragmentAdvising = new FragmentAdvising();
        fragmentMemories = new FragmentMemories();
        fragmentSettings = new FragmentSettings();
        fragmentPlayground = new FragmentPlayground();


============= UPDATE =================


Problem was solved. I didn't have to use OnSavedInstanceState. I used a Helperclass to store the variable of the Chronometerbase. In OnCreate method i check if the variable is not null, then restore the before saved base. 

在 set fragment 方法中,首先找到具有 id 的 fragment 然后检查它是否不是 null 替换那个

Fragment fragment = getSupportFragmentManager().findFragmentByTag(TAG_PLACEHOLDER);
    if (fragment == null) {
        fragment = new PlaceholderFragment();
    }
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.container, fragment, TAG_PLACEHOLDER)
            .commit();

注意:您必须在片段中添加标签