2013-02-22 85 views
30

我在我的MainActivity中有一個ListFragment。這是我如何設置我的片段對象。有沒有辦法從棧頂獲取碎片?

FragmentManager fragmentManager = activity.getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
Fragment newFragment = new MyFragment(); 
fragmentTransaction.replace(R.id.framecontainer, newFragment, "tag"); 
fragmentTransaction.addToBackStack(null); 
fragmentTransaction.commit(); 

問題是,當用戶按下後退按鈕,我必須這樣做,至少,通過調用

getActionBar().setTitle(title); 
getActionBar().setDisplayHomeAsUpEnabled(isEnabled); 
invalidateOptionsMenu(); 

更改操作欄和菜單我都知道什麼樣的片段目前呈現,以便我知道如何設置操作欄。我將片段中的設置選項存儲爲參數。

String title = fragment.getArguments().getString("KEY_TITLE"); 
boolean isEnabled = fragment.getArguments().getBoolean("KEY_ISENABLED"); 

我做搜索有關的問題,我意識到我可以通過調用

MyFragment fragment = (MyFragment) getSupportFragmentManager() 
     .findFragmentByTag("tag"); 

然而得到的片段,我要所有的標籤存儲在自定義堆棧,並調用流行( )每當用戶在onBackPressed()中按下按鈕時。

所以,我的問題是,有沒有辦法讓我直接從堆棧中獲取當前可見片段?

注意:請記住片段類型不同,不僅僅是MyFragment。

回答

52

一些像這樣的東西應該幫助你的活動身影這一點上backpress:

private Fragment getCurrentFragment(){ 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); 
    Fragment currentFragment = fragmentManager.findFragmentByTag(fragmentTag); 
    return currentFragment; 
} 

@Override 
public void onBackPressed() { 
    Fragment fragmentBeforeBackPress = getCurrentFragment(); 
    // Perform the usual back action 
    super.onBackPressed(); 
    Fragment fragmentAfterBackPress = getCurrentFragment(); 
} 

希望這有助於。

+6

看來,如果我在你的方式做到這一點,我必須設置* * fragmentTransaction.addToBackStack(標籤)**;否則,我會得到一個NullPointerException。所以** fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName(); **不參考標記名稱 – 2013-02-22 16:59:10

+1

是的...你將不得不檢查空值和不良數學((getBackStackEntryCount-1)> 0等)。我有點寫得太快了。另外,沒有標籤添加的fragements會顯示爲空。 – petey 2013-02-22 17:25:52

+0

如果我使用addToBackStack(null),它會繼續工作嗎? – umerk44 2016-04-06 20:32:16

20
FragmentManager.findFragmentById(fragmentsContainerId) 

function鏈接返回到頂部在堆棧中Fragment。用例:

fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer); 
      if(fr!=null){ 
       Log.e("fragment=", f.getClass().getSimpleName()); 
      } 
     } 
    }); 
+0

這看起來有點怪異......但對我來說確實很好:)。文檔確實說它搜索的是後臺,所以希望它始終在堆棧的頂部搜索所有版本的Android(手指交叉)。 – delrocco 2014-07-24 21:39:17

+0

我一直在尋找這個這麼久。感謝您澄清這位聽衆如何工作 – mikebertiean 2016-12-13 20:09:41

1

已經有標記爲正確的答案和我的其他信息的不會 是不同的這一點。但是,當使用接收機嘗試 判斷接收方來自哪裏的片段是當前棧頂的 片段時,我遇到了麻煩。你可以很容易地運行在很多NPE和索引越界之外。 因此,我寫了這個,也許它有助於某人。

private boolean isFragmentOnTop(Activity parentActivity, final String fragmentName){ 
     FragmentManager fmManager = parentActivity.getFragmentManager(); 
     if(fmManager.getBackStackEntryCount() == 0){ 
      LOG.i("BackStack entry count is 0: " + this); 
      return false; 
     } 
     String fragmentNameOnStackTop = ""; 
     final FragmentManager.BackStackEntry topEntry = fmManager.getBackStackEntryAt(fmManager.getBackStackEntryCount() -1); 
     if(topEntry != null) { 
      fragmentNameOnStackTop = topEntry.getName(); 
     } 
     LOG.d("Got fragments name: " + fragmentNameOnStackTop); 
     return fragmentNameOnStackTop != null ? fragmentNameOnStackTop.equals(fragmentName) : false; 
    } 

請注意,這適用於有一些片段的活動。請注意,如果您是使用ViewPager childfragmentmanager的 。

而且不要忘記設置fragmentName在FragmentTransaction.addToBackStack(fragmentName)

0

這個輔助方法從堆棧的頂部得到片段:

public Fragment getTopFragment() { 
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 
     return null; 
    } 
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); 
    return getSupportFragmentManager().findFragmentByTag(fragmentTag); 
} 
相關問題