如何在后台堆栈中用另一个片段替换多个片段?
How to replace more than one fragments with another one in the back stack?
我在后台堆栈中有以下片段A、B、C。然后我想添加片段 D,但是在后面的堆栈中我想放 A 和 D 而不是 A, B , C, D。
问题是当我尝试使用 transaction.remove()
删除 B 和 C 时,backStackEntryCount
仍然是旧的,它在按下后退时会出现空白屏幕。有办法处理吗?
当我使用popBackStack()
时,片段A然后片段D,这会产生奇怪的动画效果。
编辑:
题目没有标注的重复,因为这道题更多的是控制返回栈中几个分片的顺序
片段A
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, FragmentA, "FragmentA");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
片段 B
fragmentTransaction.replace(R.id.fragment_container, FragmentB, "FragmentB");
片段 C
fragmentTransaction.replace(R.id.fragment_container, FragmentC, "FragmentC");
片段 D
fragmentTransaction.replace(R.id.fragment_container, FragmentD, "FragmentD");
现在你的 onBackPressed() 在 activity
@Override
public void onBackPressed() {
int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
//If the last fragment was named/tagged "three"
if (getSupportFragmentManager().getFragments().get(lastStack).getTag().toString()=="FragmentD"){
getSupportFragmentManager().popBackStackImmediate();//skip c
getSupportFragmentManager().popBackStackImmediate();//skip B
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentA");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
return;
}
} catch (Exception e) {
e.printStackTrace();
}
super.onBackPressed();
}
为每个片段制作fragment_container并继续替换最新片段的fragment_container..
别忘了:
addToBackStack(null);
添加到 Backstack 时,您可以包含一个名称,以便在您处于特定状态时将 backstack 弹出到该名称。基于 FragmentManager#popBackStack(string, int); 的文档:
Pop the last fragment transition from the manager's fragment back stack. If there is nothing to pop, false is returned. This function is asynchronous -- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.
Parameters
name String: If non-null, this is the name of a previous back state to look for; if found, all states up to that state will be popped. The POP_BACK_STACK_INCLUSIVE flag can be used to control whether the named state itself is popped. If null, only the top state is popped.
flags int: Either 0 or POP_BACK_STACK_INCLUSIVE.
所以在这种情况下你:
将片段 A 添加到容器和根后台堆栈。给它起个名字,以便弹出时可以引用它。
片段 A:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentA, "FragmentA")
.addToBackStack("first")
.commit();
将片段 B 添加到容器中(替换或添加,无所谓)。如果您愿意,可以使用“null”或其他名称添加到后台堆栈。它必须不同于“first”。
片段 B:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentB, "FragmentB")
.addToBackStack(null)
.commit();
像使用片段 B 一样添加或替换为片段 C。
片段 C:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentC, "FragmentC")
.addToBackStack(null)
.commit();
像使用片段 B 和 C 一样添加或替换为片段 D。
片段 D:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentD, "FragmentD")
.addToBackStack(null)
.commit();
然后,在 onBackPressed()
中,您首先检查“FragmentD”是否在堆栈中。如果是,则一直弹出到根(在本例中为“第一”)。如果没有,请像往常一样处理后压。
@Override
public void onBackPressed() {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag("FragmentD") != null) {
fm.popBackStack("first", 0); // Pops everything up to "first"
} else {
super.onBackPressed(); // Pops backstack like normal or leaves App if at base.
}
}
这应该做的是让您的用户在片段 A、B 或 C 中按下后退按钮时“返回”。然后当他们最终进入片段 D 时,它会一直弹出到 A.
我在后台堆栈中有以下片段A、B、C。然后我想添加片段 D,但是在后面的堆栈中我想放 A 和 D 而不是 A, B , C, D。
问题是当我尝试使用 transaction.remove()
删除 B 和 C 时,backStackEntryCount
仍然是旧的,它在按下后退时会出现空白屏幕。有办法处理吗?
当我使用popBackStack()
时,片段A然后片段D,这会产生奇怪的动画效果。
编辑: 题目没有标注的重复,因为这道题更多的是控制返回栈中几个分片的顺序
片段A
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, FragmentA, "FragmentA");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
片段 B
fragmentTransaction.replace(R.id.fragment_container, FragmentB, "FragmentB");
片段 C
fragmentTransaction.replace(R.id.fragment_container, FragmentC, "FragmentC");
片段 D
fragmentTransaction.replace(R.id.fragment_container, FragmentD, "FragmentD");
现在你的 onBackPressed() 在 activity
@Override
public void onBackPressed() {
int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
//If the last fragment was named/tagged "three"
if (getSupportFragmentManager().getFragments().get(lastStack).getTag().toString()=="FragmentD"){
getSupportFragmentManager().popBackStackImmediate();//skip c
getSupportFragmentManager().popBackStackImmediate();//skip B
Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentA");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
return;
}
} catch (Exception e) {
e.printStackTrace();
}
super.onBackPressed();
}
为每个片段制作fragment_container并继续替换最新片段的fragment_container.. 别忘了:
addToBackStack(null);
添加到 Backstack 时,您可以包含一个名称,以便在您处于特定状态时将 backstack 弹出到该名称。基于 FragmentManager#popBackStack(string, int); 的文档:
Pop the last fragment transition from the manager's fragment back stack. If there is nothing to pop, false is returned. This function is asynchronous -- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.
Parameters
name String: If non-null, this is the name of a previous back state to look for; if found, all states up to that state will be popped. The POP_BACK_STACK_INCLUSIVE flag can be used to control whether the named state itself is popped. If null, only the top state is popped.
flags int: Either 0 or POP_BACK_STACK_INCLUSIVE.
所以在这种情况下你:
将片段 A 添加到容器和根后台堆栈。给它起个名字,以便弹出时可以引用它。
片段 A:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentA, "FragmentA")
.addToBackStack("first")
.commit();
将片段 B 添加到容器中(替换或添加,无所谓)。如果您愿意,可以使用“null”或其他名称添加到后台堆栈。它必须不同于“first”。
片段 B:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentB, "FragmentB")
.addToBackStack(null)
.commit();
像使用片段 B 一样添加或替换为片段 C。
片段 C:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentC, "FragmentC")
.addToBackStack(null)
.commit();
像使用片段 B 和 C 一样添加或替换为片段 D。
片段 D:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, FragmentD, "FragmentD")
.addToBackStack(null)
.commit();
然后,在 onBackPressed()
中,您首先检查“FragmentD”是否在堆栈中。如果是,则一直弹出到根(在本例中为“第一”)。如果没有,请像往常一样处理后压。
@Override
public void onBackPressed() {
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag("FragmentD") != null) {
fm.popBackStack("first", 0); // Pops everything up to "first"
} else {
super.onBackPressed(); // Pops backstack like normal or leaves App if at base.
}
}
这应该做的是让您的用户在片段 A、B 或 C 中按下后退按钮时“返回”。然后当他们最终进入片段 D 时,它会一直弹出到 A.