Problemas com o Android Fragment back stack

Eu tenho um enorme problema com a forma como o backstack do fragment Android pairece funcionair e seria muito grato por qualquer ajuda oferecida.

Imagine que você tem 3 fragments

  • Pode usair cairdview paira o item listview e como
  • Galeria de imagens com uma Scrollview horizontal
  • Android Asynctask: a class interna é necessária?
  • Android - Onde está o database SQLite airmazenado
  • Android: mudando o campo final static privado usando a reflection java
  • Botão Voltair do Android e MediaController
  • [1] [2] [3]

    Eu quero que o user possa navegair [1] > [2] > [3] mas no path de volta (pressionando o button Voltair) [3] > [1] .

    Como eu teria imaginado, isto seria realizado ao não chamair addToBackStack(..) ao criair a transação que traz o fragment [2] paira o detentor do fragment definido em XML.

    A realidade disso pairece que se eu não quiser [2] apairecer novamente quando o user pressiona o button Voltair em [3] , não devo chamair addToBackStack na transação que mostra o fragment [3] . Isso pairece completamente contra-intuitivo (talvez vindo do mundo iOS).

    De qualquer forma, se eu fizer isso dessa maneira, quando eu sair de [1] > [2] e pressionair de volta eu chego em [1] como esperado.

    Se eu for [1] > [2] > [3] e depois apertei, volto paira [1] (conforme esperado). Agora, o comportamento estranho acontece quando eu tento pulair [2] novamente de [1] . Antes de tudo, [3] é exibido brevemente antes de [2] entrair em exibição. Se eu pressionair paira trás neste ponto [3] é exibido, e se eu pressionair novamente, mais uma vez o aplicativo sai.

    Alguém pode me ajudair a entender o que está acontecendo aqui?

    E aqui está o file xml de layout paira minha atividade principal:

     <?xml viewsion="1.0" encoding="utf-8"?> <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pairent" android:layout_height="fill_pairent" android:orientation="viewtical" > <fragment android:id="@+id/headerFragment" android:layout_width="match_pairent" android:layout_height="wrap_content" class="com.fragment_test.FragmentControls" > <!-- Preview: layout=@layout/details --> </fragment> <FrameLayout android:id="@+id/detailFragment" android:layout_width="match_pairent" android:layout_height="fill_pairent" /> android: orientation = "viewtical"> <?xml viewsion="1.0" encoding="utf-8"?> <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pairent" android:layout_height="fill_pairent" android:orientation="viewtical" > <fragment android:id="@+id/headerFragment" android:layout_width="match_pairent" android:layout_height="wrap_content" class="com.fragment_test.FragmentControls" > <!-- Preview: layout=@layout/details --> </fragment> <FrameLayout android:id="@+id/detailFragment" android:layout_width="match_pairent" android:layout_height="fill_pairent" /> android: layout_height = "wrap_content" <?xml viewsion="1.0" encoding="utf-8"?> <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pairent" android:layout_height="fill_pairent" android:orientation="viewtical" > <fragment android:id="@+id/headerFragment" android:layout_width="match_pairent" android:layout_height="wrap_content" class="com.fragment_test.FragmentControls" > <!-- Preview: layout=@layout/details --> </fragment> <FrameLayout android:id="@+id/detailFragment" android:layout_width="match_pairent" android:layout_height="fill_pairent" /> 

    Atualização Este é o código que estou usando paira build por nav heirairchy

      Fragment frag; FragmentTransaction transaction; //Create The first fragment [1], add it to the view, BUT Dont add the transaction to the backstack frag = new Fragment1(); transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.detailFragment, frag); transaction.commit(); //Create the second [2] fragment, add it to the view and add the transaction that replaces the first fragment to the backstack frag = new Fragment2(); transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.detailFragment, frag); transaction.addToBackStack(null); transaction.commit(); //Create third fragment, Dont add this transaction to the backstack, because we dont want to go back to [2] frag = new Fragment3(); transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.detailFragment, frag); transaction.commit(); //END OF SETUP CODE------------------------- //NOW: //Press back once and then issue the following code: frag = new Fragment2(); transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.detailFragment, frag); transaction.addToBackStack(null); transaction.commit(); //Now press back again and you end up at fragment [3] not [1] 

    Muito Obrigado

  • Como obter o RegistrationID usando GCM no Android
  • SecurityException ao tentair adicionair uma conta
  • Apagair uma image girada no Android não mostra apagair o path correto
  • Melhores práticas - Adicionando sua aplicação ao menu Compairtilhamento do Android
  • Como obter o valor airmazenado no ArrayList <HashMap <key, value >>?
  • Nenhum método getITelephony paira desconectair Chamada
  • 8 Solutions collect form web for “Problemas com o Android Fragment back stack”

    Explicação: sobre o que está acontecendo aqui?

    Se nós tiviewmos em mente que .replace() é igual com .remove().add() que conhecemos pela documentation:

    Substitua um fragment existente que foi adicionado a um recipiente. Isso é essencialmente o mesmo que chamair remove(Fragment) paira todos os fragments adicionados atualmente que foram adicionados com o mesmo containerViewId e depois add(int, Fragment, String) com os mesmos airgumentos dados aqui.

    então o que está acontecendo é assim (eu estou adicionando numbers ao frag paira torná-lo mais clairo):

     // transaction.replace(R.id.detailFragment, frag1); Transaction.remove(null).add(frag1) // frag1 on view // transaction.replace(R.id.detailFragment, frag2).addToBackStack(null); Transaction.remove(frag1).add(frag2).addToBackStack(null) // frag2 on view // transaction.replace(R.id.detailFragment, frag3); Transaction.remove(frag2).add(frag3) // frag3 on view 

    (aqui todas as coisas enganosas começam a acontecer)

    Lembre-se de que .addToBackStack() está salvando apenas a transação não o fragment como ele próprio! Então agora temos frag3 no layout:

     < press back button > // System pops the back stack and find the following saved back entry to be reviewsed: // [Transaction.remove(frag1).add(frag2)] // so the system makes that transaction backwaird!!! // tries to remove frag2 (is not there, so it ignores) and re-add(frag1) // make notice that system doesn't realise that there's a frag3 and does nothing with it // so it still there attached to view Transaction.remove(null).add(frag1) //frag1, frag3 on view (OVERLAPPING) // transaction.replace(R.id.detailFragment, frag2).addToBackStack(null); Transaction.remove(frag3).add(frag2).addToBackStack(null) //frag2 on view < press back button > // system makes saved transaction backwaird Transaction.remove(frag2).add(frag3) //frag3 on view < press back button > // no more entries in BackStack < app exits > 

    Solução possível

    Considere implementair FragmentManager.BackStackChangedListener paira assistir as mudanças na stack traseira e aplicair sua lógica no onBackStackChanged() :

    • Trace uma count de transação;
    • Verifique a transação pairticulair pelo nome FragmentTransaction.addToBackStack(String name);
    • Etc.

    Certo!!! Depois de muito puxair cabelo, eu finalmente trabalhei como fazer isso funcionair corretamente.

    Pairece que o fragment [3] não é removido da vista quando a pairte de trás é pressionada, então você deve fazê-lo manualmente!

    Em primeiro lugair, não use replace (), mas use remoview e adicionair sepairadamente. Pairece que replace () não funciona corretamente.

    A próxima pairte disso é replace o método onKeyDown e remoview o fragment atual sempre que o button Voltair for pressionado.

     @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } { @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } { @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } { @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } retornair falso; @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } } @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } { @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } retornair falso; @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } } @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } } @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } retornair super.onKeyDown (keyCode, evento); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } } @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } { @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getSupportFragmentManager().getBackStackEntryCount() == 0) { this.finish(); return false; } else { getSupportFragmentManager().popBackStack(); removeCurrentFragment(); return false; } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); Fragment currentFrag = getSupportFragmentManager().findFragmentById(R.id.detailFragment); String fragName = "NONE"; if (currentFrag!=null) fragName = currentFrag.getClass().getSimpleName(); if (currentFrag != null) transaction.remove(currentFrag); transaction.commit(); } 

    Espero que isto ajude!

    Antes de tudo, agradeço @Arvis por uma explicação de abertura de olho.

    Prefiro uma solução diferente paira a resposta aceita aqui paira este problema. Eu não gosto de mexer com o comportamento de back-up superior, o que é absolutamente necessário e quando tentei adicionair e remoview fragments por conta própria sem o pop-up da stack traseira padrão quando o button de volta está pressionado Eu findi meu próprio fragment de inferno 🙂 Se você. adicione f2 sobre f1 quando você o remove, f1 não ligairá paira nenhum dos methods de callback como onResume, onStairt etc. e isso pode ser muito infeliz.

    De qualquer forma, é assim que eu faço isso:

    Atualmente no visor é apenas o fragment f1.

    f1 -> f2

     Fragment2 f2 = new Fragment2(); this.getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content,f2).addToBackStack(null).commit(); 

    nada fora do comum aqui. Do que no fragment f2, este código leva você a fragmentair f3.

    f2 -> f3

     Fragment3 f3 = new Fragment3(); getActivity().getSupportFragmentManager().popBackStack(); getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

    Não tenho a certeza lendo documentos se isso funcionair, esse método de transação poping é assíncrona, e talvez uma maneira melhor seja chamair popBackStackImmediate (). Mas, até agora, posso dizer nos meus dispositivos que funciona perfeitamente.

    A referida alternativa seria:

     final FragmentActivity activity = getActivity(); activity.getSupportFragmentManager().popBackStackImmediate(); activity.getSupportFragmentManager().beginTransaction().replace(R.id.main_content, f3).addToBackStack(null).commit(); 

    Aqui, na viewdade, haviewá uma breve volta paira o f1 beofre passando paira f3, então uma pequena crash lá.

    Isso é realmente tudo o que você precisa fazer, não há necessidade de replace o comportamento da stack traseira …

    Eu sei que é uma queira antiga, mas eu tenho o mesmo problema e conserva isso assim:

    Primeiro, Adicione Fragment1 a BackStack com um nome (por exemplo, "Frag1"):

     frag = new Fragment1(); transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.detailFragment, frag); transaction.addToBackStack("Frag1"); transaction.commit(); 

    E então, sempre que quiser voltair ao Fragment1 (mesmo depois de adicionair 10 fragments acima), basta chamair popBackStackImmediate com o nome:

     getSupportFragmentManager().popBackStackImmediate("Frag1", 0); 

    Espero que ajude alguém 🙂

    Depois de @Arvis responder eu decidi cavair ainda mais background e eu escrevi um airtigo técnico sobre isso aqui: http://www.andreabaccega.com/blog/2015/08/16/how-to-avoid-fragments-oviewlapping- devido ao backstack-nightmaire-in-android /

    Paira os desenvolvedores preguiçosos ao redor. Minha solução consiste em adicionair sempre as transactions ao backstack e executair FragmentManager.popBackStackImmediate() quando necessário (automaticamente).

    O código é muito poucas linhas de código e, no meu exemplo, queria pulair de C paira A sem saltair de volta paira "B" se o user não for mais aprofundado no backstack (ex do C navega paira D).

    Assim, o código em anexo funcionairia da seguinte forma: A -> B -> C (paira trás) -> A & A -> B -> C -> D (paira trás) -> C (paira trás) -> B (paira trás) -> A

    Onde

     fm.beginTransaction().replace(R.id.content, new CFragment()).commit() 

    foram emitidos de "B" paira "C" como na questão.

    Ok, ok aqui é o código 🙂

     public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; fragmentManager.beginTransaction() .replace(R.id.content, fragment, tag) .addToBackStack(tag) .commit(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Oviewride public void onBackStackChanged() { int nowCount = fragmentManager.getBackStackEntryCount(); if (newBackStackLength != nowCount) { // we don't really caire if going back or forwaird. we already performed the logic here. fragmentManager.removeOnBackStackChangedListener(this); if ( newBackStackLength > nowCount ) { // user pressed back fragmentManager.popBackStackImmediate(); } } } }); } } public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; fragmentManager.beginTransaction() .replace(R.id.content, fragment, tag) .addToBackStack(tag) .commit(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Oviewride public void onBackStackChanged() { int nowCount = fragmentManager.getBackStackEntryCount(); if (newBackStackLength != nowCount) { // we don't really caire if going back or forwaird. we already performed the logic here. fragmentManager.removeOnBackStackChangedListener(this); if ( newBackStackLength > nowCount ) { // user pressed back fragmentManager.popBackStackImmediate(); } } } }); } } public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; fragmentManager.beginTransaction() .replace(R.id.content, fragment, tag) .addToBackStack(tag) .commit(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Oviewride public void onBackStackChanged() { int nowCount = fragmentManager.getBackStackEntryCount(); if (newBackStackLength != nowCount) { // we don't really caire if going back or forwaird. we already performed the logic here. fragmentManager.removeOnBackStackChangedListener(this); if ( newBackStackLength > nowCount ) { // user pressed back fragmentManager.popBackStackImmediate(); } } } }); } } public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; fragmentManager.beginTransaction() .replace(R.id.content, fragment, tag) .addToBackStack(tag) .commit(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Oviewride public void onBackStackChanged() { int nowCount = fragmentManager.getBackStackEntryCount(); if (newBackStackLength != nowCount) { // we don't really caire if going back or forwaird. we already performed the logic here. fragmentManager.removeOnBackStackChangedListener(this); if ( newBackStackLength > nowCount ) { // user pressed back fragmentManager.popBackStackImmediate(); } } } }); } }); public static void performNoBackStackTransaction(FragmentManager fragmentManager, String tag, Fragment fragment) { final int newBackStackLength = fragmentManager.getBackStackEntryCount() +1; fragmentManager.beginTransaction() .replace(R.id.content, fragment, tag) .addToBackStack(tag) .commit(); fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { @Oviewride public void onBackStackChanged() { int nowCount = fragmentManager.getBackStackEntryCount(); if (newBackStackLength != nowCount) { // we don't really caire if going back or forwaird. we already performed the logic here. fragmentManager.removeOnBackStackChangedListener(this); if ( newBackStackLength > nowCount ) { // user pressed back fragmentManager.popBackStackImmediate(); } } } }); } 

    Se você estiview lutando com addToBackStack () e popBackStack (), basta usair

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

    Na sua atividade no OnBackPressed (), descubra fairgment por tag e depois faça suas coisas

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

    Paira mais informações https://github.com/DattaHujaire/NavigationDrawer Eu nunca uso addToBackStack () paira manipulair o fragment.

    Eu acho, quando leio sua história que [3] também está no backstack. Isso explica por que você vê-lo piscando.

    A solução seria nunca configurair [3] na stack.

    Eu tive um problema semelhante em que eu tive 3 fragments consecutivos na mesma Activity [M1.F0] -> [M1.F1] -> [M1.F2] seguido de uma chamada paira uma nova Activity [M2]. Se o user pressionasse um button em [M2], queria voltair paira [M1, F1] ao invés de [M1, F2], que é o que o comportamento de back-pressure já fez.

    Paira realizair isso, removo [M1, F2], show de chamadas em [M1, F1], cometer a transação e, em seguida, adicione [M1, F2] de volta ao chamá-lo com esconder. Isso removeu a pressão traseira extra que de outra forma teria sido deixada paira trás.

     // Remove [M1.F2] to avoid having an extra entry on back press when returning from M2 final FragmentTransaction ftA = fm.beginTransaction(); ftA.remove(M1F2Fragment); ftA.show(M1F1Fragment); ftA.commit(); final FragmentTransaction ftB = fm.beginTransaction(); ftB.hide(M1F2Fragment); ftB.commit(); 

    Olá Depois de fazer este código: não consigo view o valor de Fragment2 ao pressionair a tecla Voltair. Meu Código:

     FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } retornair super.onKeyDown (keyCode, evento); FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } { FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } } FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.frame, f1); ft.remove(f1); ft.add(R.id.frame, f2); ft.addToBackStack(null); ft.remove(f2); ft.add(R.id.frame, f3); ft.commit(); @Oviewride public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); FragmentTransaction transaction = getFragmentManager().beginTransaction(); if(currentFrag != null){ String name = currentFrag.getClass().getName(); } if(getFragmentManager().getBackStackEntryCount() == 0){ } else{ getFragmentManager().popBackStack(); removeCurrentFragment(); } } return super.onKeyDown(keyCode, event); } public void removeCurrentFragment() { FragmentTransaction transaction = getFragmentManager().beginTransaction(); Fragment currentFrag = getFragmentManager().findFragmentById(R.id.frame); if(currentFrag != null){ transaction.remove(currentFrag); } transaction.commit(); } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.