【问题标题】:Backstack Fragment not appearing in front on Back button prerssedBackstack Fragment 没有出现在按下后退按钮的前面
【发布时间】:2015-06-29 14:58:00
【问题描述】:

在写这篇文章之前,我已经经历了很多 stackoverflow 问题。我对 Fragment 中的 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 保持运行。

更新

当我从

导航时

片段1>片段2

然后按下fragment2 上的返回按钮,我将来到fragment1 但如果从

移动

片段1 > 片段2> 片段3

我在onBackPressed() 方法上得到堆栈条目计数1,但在设备屏幕上它仍然显示fragment3。现在再次按下后退按钮将使我退出应用程序,但 fragment1 不会出现在屏幕上。如此令人费解的是为什么会这样?

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

【问题讨论】:

  • 你试过简单地打电话给getFragmentManager().popBackStack()吗?
  • @tyczj popBackStack 什么都不返回。
  • @joaquin 我试过但没有运气:(
  • @tyczj 我试过用 popBackStackImmediate 它返回 true 但屏幕上没有变化。

标签: android android-fragments


【解决方案1】:

调用replace() 将删除前一个片段,片段1 应该使用replace() 调用,片段2 和3 应该使用add() 调用,您还应该将最后一个事务添加到后台堆栈(调用片段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),并且由于在添加片段 3 之前片段 2 已被弹出,因此onBackPressed 将显示第一个片段。

【讨论】:

  • 抱歉,add 甚至不会在屏幕上显示第二个片段,我已经尝试过了。
  • 我的错!我忘记使用 show() 和 hide(),现在将编辑我的答案,是的,我已经尝试过了。
  • 在显示片段 3 之前,还有一件事片段 1 出现了一段时间。
  • 请看我的编辑,我在添加片段 2 之前隐藏片段 1,并在 onBackPressed() 中显示它。
  • 仍然 fragment2 没有出现在屏幕上,伙计,我不明白它是如何为你工作的?
【解决方案2】:

感谢 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 );

您必须将该交易保存在您实际按下后退按钮的后台堆栈中。

我对@9​​87654323@ 方法做了一个小改动,当用户按下fragment1 上的返回按钮时,它允许应用程序存在。

我的onBackPressed() 现在看起来像这样

@Override
    public void onBackPressed() {

        if( manager.getBackStackEntryCount() > 0 ) {
            getSupportFragmentManager().popBackStack(
                    scoreTrackerIntroFragment.getClass().getName(),
                    FragmentManager.POP_BACK_STACK_INCLUSIVE );
        }else {

            super.onBackPressed();
        }

    }

哇!现在我对这个“Backstack”的家伙很清楚了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2016-11-04
    • 2021-09-18
    • 1970-01-01
    相关资源
    最近更新 更多