【问题标题】:Fragment does not pop out from backstack?片段不会从后台弹出?
【发布时间】:2017-11-10 09:00:52
【问题描述】:

我有三个片段 A、B 和 C

这是路径:A -> B -> C : A 去 B 和 B 去 C

当我从片段 C 回去时,我想去片段 A。

  • A C 回到根片段 A
  • A B 回到根片段 A

但是我的问题是当我在片段 C 中按下回时,我得到了这种行为:片段 C 似乎没有从后台堆栈中清除:

至于我的代码,这是replaceFragment的方法:

public void replaceFragment(Fragment fragment, boolean withBackStack) {
    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    String fragmentTag = fragment.getClass().getName();
    fragmentTransaction.replace(R.id.frame, fragment, fragmentTag);
    if (withBackStack)
        fragmentTransaction.addToBackStack(fragmentTag);
    try {
        fragmentTransaction.commitAllowingStateLoss();
    } catch (IllegalStateException ex) {
        ex.printStackTrace();
    }
}

首先我在MainActivity中调用replaceFragment(new AFragment(), false);,然后在Fragment A中,当我点击按钮时,我调用mListener.replaceFragment(new BFragment(), true); 最后,在Fragment B中,当我点击按钮时,我调用了mListener.replaceFragment(new CFragment(), false);

有人对此行为有解释吗?当我点击 backpressed 时,最后一个片段 C 不应该被清除?

Here ,你会找到整个例子。 提前致谢!

【问题讨论】:

  • 分享您的 xml 文件。
  • 在xml文件中,我只是在fragment中添加了一个简单的textview,在activity中添加了一个frameLayout。无论如何,这是示例的链接:github.com/imen-nmn/BackStackExample
  • 我检查了你的代码,我错过了在你的片段 xml 文件中设置背景颜色。这就是它重叠的原因。
  • 将背景颜色设置为片段 A、B、C 的父视图,您将永远不会再遇到这个问题
  • 添加颜色不会从后台删除片段。您需要为第一个片段调用 add (而不是 replace ),然后对所有其他片段使用 replace 。 OnBack 按使用代码 getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

标签: android android-fragments fragment-backstack


【解决方案1】:

由于您没有在 backpress 时将 fragC 添加到 backstack 不会弹出存储的事务,因此它不会被删除。相反,您必须通过覆盖 backpress 来删除片段。Overiride backpress 并检查 fragC 并将其删除,然后调用pospstack 弹回存储的事务。

还将片段的实例存储为全局,以检查片段是否为 fragC。

private Fragment mFragment;

在你的方法中存储实例

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        Fragment fragment = getSupportFragmentManager().findFragmentByTag(mFragment.getClass().getName());
        if (fragment != null && fragment.getClass().getName().equalsIgnoreCase(CFragment.class.getName())) {
            getSupportFragmentManager().beginTransaction().remove(mFragment).commit();
        }
        getSupportFragmentManager().popBackStackImmediate();
    } else {
        super.onBackPressed();
    }
}

【讨论】:

  • 正确的是,当我从 C 返回时,我将我重定向到 A 。但是当我从 B 返回时,它卡在 B 中。另外,我正在寻找解释,为什么在我的示例中 C 没有从 backstack 中清除?
  • 对不起,这是一个小错误..查看更新的代码
  • 你没有将 C 添加到 backstack..因此它不会在 Backpress 上被删除。添加到 backstack 的片段只是在按下返回时将被清除的片段
  • 通过add、replace和addstacktobackstack的区别,你就会明白了。希望我的回答对你有帮助:)
  • 欢迎您。您可以覆盖 backpress,但不应与它的 android 系统 backpress 方法混淆。如果您要添加更多片段,您可以检查并删除 backpress 中的片段。
【解决方案2】:

根据@Anonymous 的回答,我找到了这个问题的通用解决方案:

  @Override
    public void onBackPressed() {
        Fragment currentFragment= getSupportFragmentManager().findFragmentById(R.id.frame);
        super.onBackPressed();

        if(currentFragment!=null && currentFragment.isVisible()) {
            getSupportFragmentManager().beginTransaction().remove(currentFragment).commit();
            getSupportFragmentManager().popBackStack(currentFragment.getTag(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }

    }

【讨论】:

    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    相关资源
    最近更新 更多