我对Android片段相当新,所以请耐心等待。
我有一堆片段使用单个活动作为主机。
在我看来,我的片段按部分分组,尽管它们仍然是模块化/可重复使用的代码。 考虑这个期望的场景:
Frag1 - > (按下一步) - > Frag2 - > (按下一步) - > Frag3 - > (按后退) - > Frag1
在浏览了一系列片段之后,我想在按下后退按钮时跳过一些先前的片段(在这种情况下,跳过片段2)。
然而,在我目前的代码中,我的问题是即使它回到Frag1,Frag3也不会从屏幕上消失。发生的事情是Frag1和Frag3都会在彼此之上变得可见。
以下是我的相关代码段:
用于创建Frag1的代码段
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
// init the fragment (with a default fragment, not null)
Fragment fragment = PlaceholderFragment.newInstance(position + 1);
// Position number from navigation sidebar starts from 0.
// Since position starts from 0, add 1 to match section number
// as implemented in {@link #onSectionAttached()}
switch(position) {
case 0:
fragment = PlaceholderFragment.newInstance(position + 1);
break;
case 1: // Frag1 case
fragment = new AddPointsFragment().newInstance(position + 1, "");
break;
default:
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
// clear all fragments from previous section from the back stack
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
// replace all currently added fragments in container and replace with the new fragment
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
用于创建Frag2的代码段
public void onEnterButtonFragmentInteraction(int sectionNumber, String cardNo) {
// TODO: Add point for given card number
int points = 5; //sample points
AddPointsSuccessFragment addPointsSuccessFragment =
new AddPointsSuccessFragment().newInstance(sectionNumber, cardNo, points);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, addPointsSuccessFragment)
.addToBackStack(null)
.commit();
}
用于创建Frag3的代码段
public void onOkButtonFragmentInteraction(int sectionNumber, String cardNo, int points) {
RedeemRewardFragment redeemRewardFragment =
new RedeemRewardFragment().newInstance(sectionNumber, cardNo, points);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, redeemRewardFragment);
fragmentTransaction.commit();
}
我目前的解决方法是在创建Frag3并运行此代码时添加.addToBackStack(null)
public void onBackButtonFragmentInteraction() {
this.onBackPressed(); // simulate pressing of activity back button
FragmentManager fragmentmanager = getFragmentManager();
fragmentmanager.popBackStack(); // pop Frag2 from back stack
}
在调用onBackPressed()方法之后。不幸的是,这种解决方法很难看,因为在转到Frag1之前,Frag2会出现瞬间出现。
答案 0 :(得分:8)
所以你的解决方案的关键是这个人:
.addToBackStack(null)
您可以为该特定事务传递字符串标识符,而不是null,例如,Fragment的类名是我们使用的(尽管如果您有多个相同的实例,那么它不会起作用)背板上的片段:
.addToBackStack(Fragment1.class.getName())
然后,如果你想从Fragment1
回到Fragment3
,只需使用下一个片段的标识符弹出,然后传递INCLUSIVE
标志(这意味着它也会弹出)您指定的下一个片段:
getFragmentManager().popBackStack(
Fragment2.class.getName(),
FragmentManager.POP_BACK_STACK_INCLUSIVE);
哪个会像预期的那样播放你的动画,但好像它们之间的片段永远不存在。我建议使用 next 片段的原因是因为您可能不希望在后台堆栈上进行第一个片段事务。
答案 1 :(得分:2)
你可以尝试这个,它应该工作,并没有给出瞬间延迟。虽然它不是很漂亮的代码,如果有人有更好的方法,请发帖。
1.给你的碎片贴一个标签。
transaction.add(R.id.main_activity_container, FirstFragment, "FirstFragment");
transaction.replace(R.id.main_activity_container, Second, "SECOND");
transaction.replace(R.id.main_activity_container, Third, "THIRD");
2.在你的frameActivity(活动)中修改你的onBackPressed()"容纳"你的碎片。
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
//If the last fragment was named/tagged "three"
if (getSupportFragmentManager().getFragments().get(lastStack).getTag().equalsIgnoreCase("THIRD")){
getSupportFragmentManager().popBackStackImmediate();
getSupportFragmentManager().popBackStackImmediate();
//Get your first fragment that you loaded in the beginning.
Fragment first = getSupportFragmentManager().findFragmentByTag("FirstFragment");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity_container, first);
transaction.commit();
return;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onBackPressed();
}
答案 2 :(得分:0)
当您显示Frag2时使用:
final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(FRAG_2);
fragmentTransaction.replace(containerID, frag2, FRAG2_TAG);
并在背面按下:
@Override
public void onBackPressed() {
final Frag2 frag2 = (Frag2)getSupportFragmentManager().findFragmentByTag(FRAG2_TAG);
if (frag2 != null && frag2.isVisible() && getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
return;
}
}
这将阻止在onBackPressed()调用后显示frag2。 避免使用popBackStack(),因为这将导致frag2生命周期触发器(onCreate,onStart,onResume ...)