Backstack碎片未出现在前面的Back按钮上

时间:2015-06-29 14:58:01

标签: android android-fragments

在写这篇文章之前,我经历了很多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不会出现在屏幕上。令人费解的是为什么会这样?

实现这一目标的任何解决方案。

2 个答案:

答案 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();
    }

现在这让你清楚,为了使用名称像

的popBackStack
manager.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" 的家伙。