在写这篇文章之前,我经历了很多stackoverflow问题。我对这个家伙Backstack的片段非常困惑。
我在Activity
中的同一个容器中添加了三个片段片段1:
private void addLandingFragment() {
landingPageFragment = LandingPageFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add( R.id.container, landingPageFragment, LANDING_PAGE_FRAGMENT_TAG );
transaction.commit();
}
片段2:
public void addIntrofragment() {
fragment2 = IntroFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment2, INTRO_PAGE_FRAGMENT_TAG);
transaction.addToBackStack(fragment2.getClass().getName() );
transaction.commit();
}
片段3:
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.commit();
}
现在我想要的是当用户按下片段3上的按钮时它应该出现在第一个片段上,所以我已经覆盖了onBackPressed()方法。
@Override
public void onBackPressed() {
manager.popBackStack(fragment2.getClass().getName() ,FragmentManager.POP_BACK_STACK_INCLUSIVE );
}
但屏幕上没有任何事情发生,它使片段3保持运行。
更新
当我从
导航时fragment1> fragment2
然后按下fragment2上的按钮,我来到fragment1但是从
移动fragment1> fragment2> fragment3
我在onBackPressed()
方法上获得堆栈条目计数1,但在设备屏幕上它仍显示fragment3。现在再次按下后退按钮将退出应用程序但片段1不会出现在屏幕上。令人费解的是为什么会这样?
实现这一目标的任何解决方案。
答案 0 :(得分:0)
调用replace()
将删除之前的片段,应使用replace()
调用片段1,并使用片段2& 3应该使用add()
调用,你还应该将最后一个事务添加到后台堆栈(调用Fragment 3)
像这样:
片段1:
private void addLandingFragment() {
landingPageFragment = LandingPageFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, landingPageFragment, LANDING_PAGE_FRAGMENT_TAG );
transaction.commit();
}
片段2:
public void addIntrofragment() {
fragment2 = IntroFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction .hide(LandingPageFragment.this);
transaction.add( R.id.container, fragment2, INTRO_PAGE_FRAGMENT_TAG);
transaction.addToBackStack(fragment2.getClass().getName() );
transaction.commit();
}
片段3:
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
fragmentManager.popBackStackImmediate(); // to remove fragment 2
transaction.add( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.addToBackStack(fragment3.getClass().getName() );
transaction.commit();
}
最后你的onBackPressed
应该是这样的:
@Override
public void onBackPressed() {
fragmentManager.popBackStackImmediate();
fragmentTransaction.show(LandingPageFragment.this);
}
因此你的onBackPressed
将始终弹出堆栈顶部片段(片段3),并且由于片段2在添加片段3之前已经弹出,然后onBackPressed
将显示第一个片段。 / p>
答案 1 :(得分:0)
感谢Silvia.H为您提供支持。我已经解决了我的问题并发现它是我最好的解决方案。
我唯一的错误是,我没有在backstack中添加fragment3
所以唯一需要的改变是
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.addToBackStack(ConnectFragment.class.getName() );
transaction.commit();
}
现在这让你清楚,为了使用名称像
的popBackStackmanager.popBackStack(fragment2.getClass().getName() ,FragmentManager.POP_BACK_STACK_INCLUSIVE );
你必须将该交易保留在实际按下后退按钮的后台。
我在onBackPressed()
方法中做了一个小改动,当用户按下fragment1上的按钮时,该方法允许应用程序存在。
我的onBackPressed()
现在看起来像这样
@Override
public void onBackPressed() {
if( manager.getBackStackEntryCount() > 0 ) {
getSupportFragmentManager().popBackStack(
scoreTrackerIntroFragment.getClass().getName(),
FragmentManager.POP_BACK_STACK_INCLUSIVE );
}else {
super.onBackPressed();
}
}
WOOP!现在我清楚这个" Backstack" 的家伙。