如何在 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();
注意:您必须在片段中添加标签
我已经对此进行了搜索,但一无所获,这有助于我解决问题。在我的代码中,我有一个带有五个片段的 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();
注意:您必须在片段中添加标签