【问题标题】:popBackStack() after addToBackStack does not workaddToBackStack 后的 popBackStack() 不起作用
【发布时间】:2014-01-16 07:52:47
【问题描述】:

我的项目包含两个片段:

  • 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>

当我想用FragmentB 替换FragmentA 时,我使用这个代码:

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

此代码运行良好。我的 FragmentA 被新的FragmentB 取代。但是当点击后退按钮时,我希望使用popBackStackImmediate()FragmentB 替换为FragmentA

这是我使用的代码:

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

函数 popBackStackImmediate 总是返回 false 并且 FragmentB 仍然在前台。

当我调用 popBackStackImmediate 时,为什么 FragmentA 没有替换 FragmentB ?有人有办法解决我的问题吗?

提前致谢

【问题讨论】:

  • 避免使用后退栈!它对整体效率并没有真正的帮助!每次要导航时都使用普通的 replace() 甚至更好的删除/添加!查看我在stackoverflow.com/questions/5802141/…的帖子

标签: android android-fragments


【解决方案1】:

您使用getSupportedFragmentManager()FragmentA 替换为FragmentB。但是你在getFragmentManager() 上拨打popBackStack()

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

这段代码应该可以解决问题:

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

【讨论】:

  • 在我的情况下,我在活动中使用supportedFragmentManager,在B中使用childFragmentManager打开C,当我在C中按下backButton时,它把我送到A而不是B
【解决方案2】:

你应该打电话

fragmentTransaction.addToBackStack(null);

在执行所有操作(例如 add()、remove() 和 replace() 之后以及在 commit() 之前)。只有这样,这个事务才会被添加到 backstack。只有这样您才能使用 Back 按钮返回到之前的片段状态。详情here.

【讨论】:

    【解决方案3】:

    问题是您正在混合 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();
    }
    

    请注意,如果您想从Fragment 代码中获取FragmentManager,您必须使用getFragmentManager 方法,如文档中所述(如果您不这样做,这可能会造成一些混乱) '没有太多经验)。

    如果您不使用支持库:

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

    您的代码将是:

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

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

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

    【讨论】:

      【解决方案4】:

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

      使用标签将片段 B 添加到活动中

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

      片段 A -> 片段 B [onBackPressed] -->片段 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 中没有任何数据!

      【讨论】:

        【解决方案5】:
        问题出在您的代码顺序上。这里有两件事你需要注意。
        1. 添加后需要使用 addToBackStack(), 替换片段。然后commmit()

        2. 然后 popBackStackImmediate 可以反转操作并且它正在工作。我希望它能解决问题。我知道这是一个旧帖子,但我 确实遇到了类似的问题,并希望此更新可以帮助其他人。下面应该是正确的顺序:

          FragmentTransaction fragmentTransaction =getSupportFragmentManager().beginTransaction();

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

        【讨论】:

          【解决方案6】:

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

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

          在 OnBackPressed() 中的 Activity 中按标签找出片段,然后做你的事情

          Fragment home = getSupportFragmentManager().findFragmentByTag("Home");
          
          if (home instanceof HomeFragment && home.isVisible()) {
              // do you stuff
          }
          

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-12-28
            • 1970-01-01
            • 1970-01-01
            • 2018-03-11
            • 2014-01-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多