2013-02-22 10 views
30

Ho un ListFragment nel mio MainActivity. Ecco come ho impostato il mio oggetto frammento.C'è un modo per ottenere frammenti dall'alto dello stack?

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

Il problema è quando l'utente preme di nuovo il pulsante, devo, almeno, modificare la barra delle azioni e il menu chiamando

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

devo sapere che tipo di frammento sta mostrando attualmente , così so come impostare la barra delle azioni. Memorizzo l'opzione di impostazione in frammento come argomenti.

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

faccio cercare la relativa domanda, e ho capito che potevo ottenere il frammento chiamando

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

Tuttavia, devo memorizzare tutti i tag in una pila su misura, e chiamare pop () ogni volta che l'utente ha premuto il pulsante Indietro in onBackPressed().

Quindi, la mia domanda è che c'è un modo per ottenere direttamente il frammento visibile corrente dallo stack?

Nota: tenere presente che i tipi di frammento sono diversi, non solo MyFragment.

risposta

52

qualche cosa come questo dovrebbe aiutare la vostra figura attività di questo fuori su 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(); 
} 

Spero che questo aiuti.

+6

Sembra che se lo faccio nel vostro senso, devo impostare * * fragmentTransaction.addToBackStack (tag) ** pure; Altrimenti, otterrei una NullPointerException. So ** fragmentManager.getBackStackEntryAt (fragmentManager.getBackStackEntryCount() - 1) .getName(); ** non si riferisce al nome dell'etichetta –

+1

Sì ... dovrai verificare null e cattiva matematica ((getBackStackEntryCount-1)> 0 e tale).Ho scritto questo troppo velocemente. Inoltre, le frazioni aggiunte senza tag verranno considerate nulle. – petey

+0

funzionerà ancora se uso addToBackStack (null)? – umerk44

20
FragmentManager.findFragmentById(fragmentsContainerId) 

function rendimenti dei collegamenti verso l'alto Fragment in backstack. Esempio di utilizzo:

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

Questo sembra strano ... ma funziona benissimo per me :). I documenti dicono che cerca nel backstack, quindi spero che cerchi sempre in cima allo stack, in tutte le versioni di Android (dita incrociate). – delrocco

+0

Ho cercato questo per così tanto tempo. Grazie per aver chiarito come funziona questo ascoltatore – mikebertiean

1

C'è già una risposta contrassegnata come corretta e il mio aggiuntive di informazioni non sarà quella diverso da quello. MA, mi sono messo nei guai quando uso un ricevitore e provo a a capire se il frammento da cui proviene il ricevitore è il frammento corrente in cima allo stack. È possibile eseguire facilmente un sacco di NPE e Index fuori limite. Perciò ho scritto questo, forse aiuta qualcuno.

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; 
    } 

Si noti che questo funziona correttamente per un'attività con alcuni frammenti. Essere consapevoli se si è utilizzando ViewPager un gestore childfragment.

E non dimenticate di impostare il fragmentName in FragmentTransaction.addToBackStack(fragmentName)

0

questo metodo di supporto ottenere frammento dalla cima della pila:

public Fragment getTopFragment() { 
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 
     return null; 
    } 
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName(); 
    return getSupportFragmentManager().findFragmentByTag(fragmentTag); 
} 
Problemi correlati