Android addToBackStack 后的 popBackStack() 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21156153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:03:22  来源:igfitidea点击:

popBackStack() after addToBackStack does not work

androidandroid-fragments

提问by reevolt

My project contains two fragment :

我的项目包含两个片段:

  • FragmentA : the fragment loaded by default when the app starts
  • FragmentB : replace the fragmentAwhen a click on a button is done.
  • FragmentA :应用启动时默认加载的片段
  • FragmentB :fragmentA在单击按钮时替换。

This is the XML of my main view :

这是我的主视图的 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>

When I wish to replace the FragmentAby the FragmentB, I use this code :

当我想以取代FragmentAFragmentB,我用这个代码:

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

This code works fine. My FragmentA is replaced by the new FragmentB. But when a click is done on the back button, I wish replace the FragmentBby the FragmentAby using popBackStackImmediate().

这段代码工作正常。我的 FragmentA 被新的FragmentB. 但是,当点击上后退按钮做的,我希望更换FragmentBFragmentA使用popBackStackImmediate()

This is the code I use:

这是我使用的代码:

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

The function popBackStackImmediatereturn always false and the FragmentBstill in foreground.

函数popBackStackImmediate返回始终为 false 并且FragmentB仍然在前台。

Why the FragmentA does not replace the FragmentB when I call popBackStackImmediate? Is anybody has an idea to solve my problem?

为什么我打电话时 FragmentA 没有替换 FragmentB popBackStackImmediate?有人有解决我的问题的想法吗?

thanks in advance

提前致谢

回答by owe

You use the getSupportedFragmentManager()to replace FragmentAby FragmentB. But you call popBackStack()on the getFragmentManager().

您使用getSupportedFragmentManager()替换FragmentAFragmentB。但是,你打电话popBackStack()getFragmentManager()

If you are adding the Fragments to the android.support.v4.app.FragmentManageryou also have to call popBackStack()on the same FragmentManager.

如果您将 Fragments 添加到android.support.v4.app.FragmentManager您还必须调用popBackStack()相同的FragmentManager.

This code should solve the problem:

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

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

回答by fasteque

The problem is you're mixing Fragmentand methods from the support library.

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

If you are using the support library, make sure:

如果您正在使用支持库,请确保:

  • your Activityextends from the android.support.v4.app.FragmentActivity
  • your Fragmentextends from android.support.v4.app.Fragment
  • use getSupportFragmentManager()to get the android.support.v4.app.FragmentManager
  • Activityandroid.support.v4.app.FragmentActivity
  • Fragmentandroid.support.v4.app.Fragment
  • 用于getSupportFragmentManager()获取android.support.v4.app.FragmentManager

Your code in the Activitywould be:

您的代码Activity将是:

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

Please be aware that if you would like to get the FragmentManagerfrom the Fragmentcode, you have to use the getFragmentManagermethod, as explained in the documentation (probably that's the cause of some confusion if you don't have much experience).

请注意,如果您想FragmentManagerFragment代码中获取,则必须使用getFragmentManager方法,如文档中所述(如果您没有太多经验,这可能是造成一些混乱的原因)。

If you are not using the support library:

如果您没有使用支持库:

  • your Activityextends from the android.app.Activity
  • your Fragmentextends from android.app.Fragment
  • use getFragmentManager()to get the android.app.FragmentManager
  • Activityandroid.app.Activity
  • Fragmentandroid.app.Fragment
  • 用于getFragmentManager()获取android.app.FragmentManager

Your code would be:

您的代码将是:

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

fragmentTransaction.commit();is not necessary in both cases, so remove it.

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

Also, please call fragmentTransaction.addToBackStack(null);just before the commitbut after the other operations.

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

回答by SohailAziz

You should call

你应该打电话

fragmentTransaction.addToBackStack(null);

after performing all operations such as add(), remove(), and replace() and Just before commit(). Only then this transaction will be added to backstack. Only then you will be able to return to previous fragment state with Backbutton. Details here.

在执行所有操作之后,例如 add()、remove() 和 replace() 以及就在 commit() 之前。只有这样,这个交易才会被添加到 backstack 中。只有这样,您才能使用“返回”按钮返回到之前的片段状态。详情请看这里

回答by TSG anti SO dark forces

I will suggest using the fragment replacement with Tag to produce the same result .

我会建议使用带有标记的片段替换来产生相同的结果。

Add the fragment B to activity with tag

将片段 B 添加到带有标签的活动中

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

Fragment A -> Fragment B [onBackPressed] -->Fragment A Override the onBackPressed() in the Activity files where ,

Fragment A -> Fragment B [onBackPressed] -->Fragment A 覆盖 Activity 文件中的 onBackPressed(),其中,

// check for fragment B and you are viewing fragment B

// 检查片段 B 并且您正在查看片段 B

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

addToBackStack("TAG") and popBackStackImmediate("TAG") always revert to fragment condition without any data in the UI right before fragment is created or added to activity !

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

回答by Stan Peng

问题在于您的代码顺序。这里有两件事你需要注意。
  1. You need to use addToBackStack() after your adding, replacing fragment. Then commmit()

  2. Then popBackStackImmediate can reverse the operation and it is working. I hope it solves the problem. I know it is an old post but I do encounter a similar problem and wish this update can help others. Below should be the correct order:

    FragmentTransaction fragmentTransaction =getSupportFragmentManager().beginTransaction();

    fragmentTransaction.replace(R.id.main_fragment_container, new FragmentB());
    
    fragmentTransaction.addToBackStack(null);
    
    fragmentTransaction.commit();
    
  1. 您需要在添加、替换片段后使用 addToBackStack()。然后提交()

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

    FragmentTransaction fragmentTransaction =getSupportFragmentManager().beginTransaction();

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

回答by Dattu Hujare

If you are Struggling with addToBackStack() and popBackStack() then simply use

如果您正在努力使用 addToBackStack() 和 popBackStack() 那么只需使用

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

In your Activity In OnBackPressed() find out fargment by tag and then do your stuff

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

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

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

For more Information https://github.com/DattaHujare/NavigationDrawerI never use addToBackStack() for handling fragment.

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