addToBackStack后不能使用popBackStack()

时间:2014-01-16 07:52:47

标签: android android-fragments

我的项目包含两个片段:

  • FragmentA:应用启动时默认加载的片段
  • FragmentB:点击按钮后替换fragmentA

这是我的主要观点的XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/main_fragment_container"
        android:name="fragmentA"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </fragment>

</LinearLayout>

当我希望用FragmentA替换FragmentB时,我会使用以下代码:

FragmentTransaction fragmentTransaction = getSupportFragmentManager()
            .beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB());
fragmentTransaction.commit();

此代码工作正常。我的FragmentA被新的FragmentB取代。但是当在后退按钮上完成点击时,我希望使用FragmentB替换FragmentA {/ 1}}。

这是我使用的代码:

popBackStackImmediate()

函数if (getSupportFragmentManager().getBackStackEntryCount() > 0){ boolean done = getFragmentManager().popBackStackImmediate(); fragmentTransaction.commit(); } 始终返回false,popBackStackImmediate仍然在前台。

为什么FragmentA在调用FragmentB时不会替换FragmentB?有人有想法解决我的问题吗?

提前致谢

6 个答案:

答案 0 :(得分:39)

您使用getSupportedFragmentManager()FragmentA替换为FragmentB。但您可以在popBackStack()上致电getFragmentManager()

如果要将片段添加到android.support.v4.app.FragmentManager,则还必须在同一popBackStack()上致电FragmentManager

此代码应解决问题:

if (getSupportFragmentManager().getBackStackEntryCount() > 0){
    boolean done = getSupportFragmentManager().popBackStackImmediate();
}

答案 1 :(得分:7)

问题是你正在混合Fragment和支持库中的方法。

如果您使用的是支持库,请确保:

  • 您的Activity来自android.support.v4.app.FragmentActivity
  • 您的Fragment来自android.support.v4.app.Fragment
  • 使用getSupportFragmentManager()获取android.support.v4.app.FragmentManager

Activity中的代码为:

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
   getSupportFragmentManager().popBackStackImmediate();
}

请注意,如果您想从FragmentManager代码中获取Fragment,则必须使用getFragmentManager方法,如文档中所述(可能是原因)如果你没有太多经验,可能会有些困惑。)

如果您没有使用支持库:

  • 您的Activity来自android.app.Activity
  • 您的Fragment来自android.app.Fragment
  • 使用getFragmentManager()获取android.app.FragmentManager

您的代码将是:

if (getFragmentManager().getBackStackEntryCount() > 0) {
   getFragmentManager().popBackStackImmediate();
}

fragmentTransaction.commit();在两种情况下都不是必需的,所以将其删除。

另外,请在fragmentTransaction.addToBackStack(null);之前,但在其他操作之后致电commit

答案 2 :(得分:5)

你应该致电

fragmentTransaction.addToBackStack(null);

执行所有操作,例如add(),remove()和replace()以及commit()之前。只有这时才会将此事务添加到Backstack中。只有这样,您才能使用 Back 按钮返回到先前的片段状态。详情here

答案 3 :(得分:1)

我建议使用Tag替换片段来产生相同的结果。

将片段B添加到带有标记

的活动
fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB(),"TAG_B");

片段A - &gt;片段B [onBackPressed] - &gt;片段A 覆盖Activity文件中的onBackPressed(),其中,

//检查片段B,你正在查看片段B

if (getSupportFragmentManager().findFragmentByTag("TAG_B")!=null)  
{
    fragmentTransaction.replace(R.id.main_fragment_container, new FragmentA(),"TAG_A");
}

addToBackStack(“TAG”)和popBackStackImmediate(“TAG”)总是在片段创建或添加到活动之前,在UI中没有任何数据的情况下恢复为片段条件!

答案 4 :(得分:0)

问题出在您的代码顺序中。这是您需要注意的两件事。
  1. 添加后,您需要使用addToBackStack(), 替换片段。然后commmit()

  2. 然后popBackStackImmediate可以撤消该操作,并且它正在运行。我希望它能解决问题。我知道这是旧帖子,但我 确实遇到类似的问题,希望此更新可以对他人有所帮助。下面应该是正确的顺序:

    FragmentTransaction fragmentTransaction =getSupportFragmentManager().beginTransaction();

    fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB());
    
    fragmentTransaction.addToBackStack(null);
    
    fragmentTransaction.commit();
    

答案 5 :(得分:-1)

如果您正在使用addToBackStack()和popBackStack()进行苦苦挣扎,那么只需使用

FragmentTransaction ft =getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, new HomeFragment(), "Home");
ft.commit();`

在你的活动中OnBackPressed()通过标签找出fargment然后做你的东西

Fragment home = getSupportFragmentManager().findFragmentByTag("Home");

if (home instanceof HomeFragment && home.isVisible()) {
    // do you stuff
}

更多信息https://github.com/DattaHujare/NavigationDrawer我从不使用addToBackStack()来处理片段。