2014-01-16 118 views
17

我的項目包含兩個片段:popBackStack()後addToBackStack不起作用

  • FragmentA:當點擊一個按鈕完成更換fragmentA:默認加載的片段時,應用程序啓動
  • FragmentB 。

這是我的主要觀點的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(); 

此代碼工作正常。我的碎片A被新的FragmentB取代。但是當點擊後退按鈕時,我希望使用popBackStackImmediate()替換FragmentBFragmentA

這是我使用的代碼:

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

功能popBackStackImmediate返回始終爲false和FragmentB仍然在前臺。

爲什麼當我撥打popBackStackImmediate時,FragmentA不會取代FragmentB?有人有解決我的問題的想法嗎?

在此先感謝

+0

避免使用背堆!它並沒有真正幫助整體效率!使用普通的替換(),甚至更好地移除/添加每次你想瀏覽!檢查我的帖子http://stackoverflow.com/questions/5802141/is-this-the-right-way-to-clean-up-fragment-back-stack-when-leaving-a-deeply-nest/26093368# 26093368 –

回答

31

您使用getSupportedFragmentManager()通過FragmentB更換FragmentA。但您撥打getFragmentManager()時請致電popBackStack()

如果要將片段添加到android.support.v4.app.FragmentManager,則還必須在相同的FragmentManager上調用popBackStack()

此代碼應解決的問題:

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

你應該叫

fragmentTransaction.addToBackStack(null); 

執行諸如加(所有操作之後),刪除(),並更換(),只是之前提交()。只有這個交易將被添加到後臺。只有這樣你才能夠返回到返回按鈕的前一個片段狀態。詳情here

3

問題是你在混合Fragment和支持庫中的方法。

如果您使用的是支持庫,確保:

  • Activityandroid.support.v4.app.FragmentActivity
  • Fragmentandroid.support.v4.app.Fragment
  • 使用getSupportFragmentManager()擴展延伸到拿到android.support.v4.app.FragmentManager

您在Activity中的代碼是:

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

請注意,如果你想從Fragment代碼得到FragmentManager,你必須使用getFragmentManager方法,如文檔中解釋(也許這是一些混亂的原因,如果你不有很多經驗)。

如果您使用的不是支持庫:

  • Activityandroid.app.Activity
  • Fragmentandroid.app.Fragment
  • 使用getFragmentManager()擴展延伸到拿到android.app.FragmentManager

您的代碼將是:

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

fragmentTransaction.commit();在這兩種情況下都不是必需的,所以刪除它。

此外,請在commit之前撥打fragmentTransaction.addToBackStack(null);,但在其他操作之後。

1

我會建議使用帶Tag的片段替換來產生相同的結果。

片段B添加到活動與標籤

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

片段A - >片段B [onBackPressed] - >片段A 重寫onBackPressed()在活動文件,其中,

//檢查片段B和你正在查看片段乙

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

addToBackStack( 「TAG」)和popBackStackImmediate( 「TAG」)總是回覆到片段康迪特在創建片段或添加到活動之前,UI中沒有任何數據!

0

如果您正在使用addToBackStack()和popBackStack()掙扎然後只需使用

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

在你的活動在OnBackPressed()按標籤找出fargment,然後做你的東西

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

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

有關更多信息https://github.com/DattaHujare/NavigationDrawer我從不使用addToBackStack()來處理片段。