ITKeyword,专注技术干货聚合推荐

注册 | 登录

解决android - Clear back stack using fragments

分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:android Fragments:管理fragment

要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager()。 你可以用FragmentManager来做以上事情:   1使用方法findF

I ported my Android app to honeycomb and I did a big refactor in order to use fragments. In my previous version, when I pressed the Home button I used to do a ACTIVITY_CLEAR_TOP in order to reset the back stack.

Now my app is just a single Activity with multiple fragments, so when I press the Home button I just replace one of the fragments inside it. How can I clear my back stack without having to use startActivity with the ACTIVITY_CLEAR_TOP flag?

android android-fragments
|
  this question
edited Mar 23 '16 at 15:56 Syakur Rahman 1,237 16 34 asked May 31 '11 at 10:49 biquillo 2,431 6 24 35      Avoid using back stacks! it doesn't really help with the overall efficiency! use plain replace() or even better remove/add every time you want to navigate! Check my post on stackoverflow.com/questions/5802141/… –  stack_ved Sep 29 '14 at 6:02

 | 

10 Answers
10

解决方法

I posted something similar here

From Joachim's answer, from Dianne Hackborn:

http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42

I ended up just using:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

But could equally have used something like:

FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

Which will pop all states up to the named one. You can then just replace the fragment with what you want


|
  this answer
edited May 23 at 12:18 Community ♦ 1 1 answered Jun 1 '11 at 8:05 PJL 10.9k 12 62 62 8   Well, it's equivalent to hitting the back button one or more times, so it changes the fragment that is currently visible. (At least when I've tried it) –  Peter Ajtai Nov 28 '11 at 0:02 6   I am having the same issue as peter. I'd like to clear all of the fragments out rather than having it cycle through them which has lots of implications. For example, you will hit lifecycle events that you don't need to by popping every fragment off of the stack sequentially. –  Brian Griffey Jan 16 '12 at 16:24 167   To go to top simply use: fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); –  Warpzit Jan 7 '13 at 10:35 42   For what it's worth, using fragmentManager. popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); worked even better for me as it prevented the fragment animations from executing –  roarster Sep 19 '13 at 19:49 11   This DOES NOT work properly - it will trigger a call to onStart of every fragment in between –  James Mar 11 '15 at 13:29  |  show more comments

To make an answer for @Warpzit's comment and make it easier for others to find... Use:

fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

|
  this answer
edited Apr 11 '16 at 17:56 Amit Kumar 1,022 1 12 40 answered Oct 18 '14 at 12:19 Morten Holmgaard 3,214 3 32 57 12   I believe popping all fragments from the backstack this way has been broken in the latest v7-appCompat library when using AppCompatActivity. After updating my app to the lastest v7-appCompat library (21.0.0) and extending the new AppCompatActivity, popping fragments in the above manner is leaving some fragments in the backstack record of the FragmentManager. I'd advise against using this. –  dell116 May 1 '15 at 18:52

 | 

With all due respect to all involved parties; I'm very surprised to see how many of you could clear the entire fragment back stack with a simple

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

According to Android documentation (regarding the name argument - the "null" in the claimed working proposals).

If null, only the top state is popped

Now, I do realize that I'm lacking knowledge of your particular implementations (like how many entries you have in the back stack at the given point in time), but I would bet all my money on the 解决方法 answer when expecting a well defined behaviour over a wider range of devices and vendors:

(for reference, something along with this)

FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {    
    fm.popBackStack();
}

|
  this answer
answered Mar 4 '15 at 9:01 dbm 6,581 5 33 50 4   for me it was not since each pop takes you internally to the onCreateView of each fragment. Where I would receive a NPE on some resource. But using fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); simply killed all the backstack. –  sud007 Dec 17 '15 at 9:28      Any insights on how to skip onCreateView calls when popping using loop? –  Ayush Goyal Dec 13 '16 at 14:40      Clearing the top most fragment (null) will clear all fragments that come after it in the back stack. –  2b77bee6-5445-4c77-b1eb-4df3e5 Jul 13 at 17:44

 | 

Accepted answer was not enough for me. I had to use :

FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
    fm.popBackStackImmediate();
}

|
  this answer
answered Oct 14 '14 at 12:45 belphegor 293 2 9 1   This was pointed out in a different answer, but just to make sure it's noted: If you pop the whole stack in a loop like this, you're going to trigger the lifecycle methods for every Fragment in between the start and end of the stack. There is a good chance that this implementation would have unintended consequences, in most use cases. It's also worth pointing out that popBackStackImmediate() performs the transaction synchronously, which is, in general, ill-advised. –  Damien Diehl Jan 13 '16 at 22:43

 | 

Works for me and easy way without using loop:

 FragmentManager fragmentManager = getSupportFragmentManager();
 //this will clear the back stack and displays no animation on the screen
 fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

|
  this answer
answered Jul 30 '15 at 9:37 Md Mohsin 687 8 21

 | 

Clear backstack without loops

String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);

Where name is the addToBackStack() parameter

getSupportFragmentManager().beginTransaction().
                .replace(R.id.container, fragments.get(titleCode))
                .addToBackStack(name)

|
  this answer
edited Nov 10 '15 at 14:26 answered May 14 '15 at 9:20 georgehardcore 717 9 9      even if u replace .fragment stack will be alive but not visible –  Asthme Jul 25 '16 at 13:59

 | 

I just wanted to add :--

Popping out from backstack using following

推荐:Fragments In Android Studio

原英文链接:Fragments in Android Studio 这篇指南将会教你在Android Studio上简单地创建和使用Fragment,并在fragment里添加一个按钮,点击按钮会发送一个个动

fragmentManager.popBackStack()

is just about removing the fragments from the transaction, no way it is going to remove the fragment from the screen. So ideally, it may not be visible to you but there may be two or three fragments stacked over each other, and on back key press the UI may look cluttered,stacked.

Just taking a simple example:-

Suppose you have a fragmentA which loads Fragmnet B using fragmentmanager.replace() and then we do addToBackStack, to save this transaction. So the flow is :--

STEP 1 -> FragmentA->FragmentB (we moved to FragmentB, but Fragment A is in background, not visible).

Now You do some work in fragmentB and press the Save button—which after saving should go back to fragmentA.

STEP 2-> On save of FragmentB, we go back to FragmentA.

STEP 3 ->So common mistake would be... in Fragment B,we will do fragment Manager.replace() fragmentB with fragmentA.

But what actually is happenening, we are loading Fragment A again, replacing FragmentB . So now there are two FragmentA (one from STEP-1, and one from this STEP-3).

Two instances of FragmentsA are stacked over each other, which may not be visible , but it is there.

So even if we do clear the backstack by above methods, the transaction is cleared but not the actual fragments. So ideally in such a particular case, on press of save button you simply need to go back to fragmentA by simply doing fm.popBackStack() or fm.popBackImmediate().

So correct Step3-> fm.popBackStack() go back to fragmentA, which is already in memory.


|
  this answer
answered Aug 31 '15 at 5:16 Nicks 7,218 2 43 52

 | 

Just use this method and pass Context & Fragment tag upto which we need to remove the backstake fragments.

Usage

clearFragmentByTag(context, FragmentName.class.getName());



public static void clearFragmentByTag(Context context, String tag) {
    try {
        FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();

        for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
            String backEntry = fm.getBackStackEntryAt(i).getName();
            if (backEntry.equals(tag)) {
                break;
            } else {
                 fm.popBackStack();
            }
        }
    } catch (Exception e) {
        System.out.print("!====Popbackstack error : " + e);
        e.printStackTrace();
    }
}

|
  this answer
answered Aug 19 '16 at 5:45 ArhatBaid 759 6 15

 | 

I got this working this way:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}

|
  this answer
answered Oct 28 '14 at 15:11 saulobrito 3,263 1 12 13

 | 

Reading the documentation and studying what the fragment id is, it appears to simply be the stack index, so this works:

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

Zero (0) is the the bottom of the stack, so popping up to it inclusive clears the stack.

CAVEAT: Although the above works in my program, I hesitate a bit because the FragmentManager documentation never actually states that the id is the stack index. It makes sense that it would be, and all my debug logs bare out that it is, but perhaps in some special circumstance it would not? Can any one confirm this one way or the other? If it is, then the above is the best solution. If not, this is the alternative:

while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }

|
  this answer
answered Jul 23 '16 at 18:24 trans 958 7 12

 | 

推荐:Android-Fragments的使用

请转原文学习: Using Fragmenys in Android - Tutorial where I found this resource:干干货分享——Android开发中学习资源大集合(译) 很素的翻译开始: 2. Fra


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。