2013-08-22 13 views
70

Sto usando il seguente metodo per passare da Frammenti (nel mio NavigationDrawer) mostrandoli/nascondendoli.Ciclo di vita dei frammenti: quale metodo viene chiamato su mostra/nascondi?

protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack) { 

     FragmentManager fragmentManager = getSupportFragmentManager(); 
     FragmentTransaction transaction = fragmentManager.beginTransaction(); 

     if (lastTag != null && !lastTag.equals("")) { 
      Fragment lastFragment = fragmentManager.findFragmentByTag(lastTag); 
      if (lastFragment != null) { 
       transaction.hide(lastFragment); 
      } 
     } 

     if (fragment.isAdded()) { 
      transaction.show(fragment); 
     } 
     else { 
      transaction.add(container, fragment, tag); 
     } 

     if (addToBackStack) { 
      transaction.addToBackStack(tag); 
     } 

     transaction.commit(); 

     // set the active tag 
     activeFragTag = tag; 
    } 

Quello che sono poco chiaro circa è quale metodo del ciclo di vita Frammenti viene chiamato quando ho mostrarlo o nasconderlo? (poiché non esiste alcun metodo come onShow() o onHide() non sono abbastanza sicuro di cosa usare). Voglio eseguire azioni specifiche mostrando e nascondendo un certo frammento.

+0

quando chiamate ** Fragment.show() ** poi, a un certo punto, il frammento attiva 'onCreate()', seguito da 'onCreateDialog()', seguito da 'onCreateView()' –

risposta

82

Simile all'attività del ciclo di vita, Android chiamate onStart() quando frammento diventa visibile. onStop() viene normalmente chiamato quando il frammento diventa invisibile, ma può anche essere chiamato in un secondo momento.

A seconda del layout, Android può chiamare anche onStart() anche se il frammento non è ancora visibile, ma appartiene a un contenitore padre visibile. Ad esempio, questo è valido per android.support.v4.view.ViewPager che richiede di sostituire il metodo Fragment.setUserVisibleHint(). In ogni caso, se è necessario registrare/annullare la registrazione di BroadcastReceivers o altri ascoltatori, è possibile utilizzare in modo sicuro i metodi onStart() e onStop() perché verranno chiamati sempre.

Nota: Alcuni contenitori di frammenti possono contenere frammenti invisibili avviati. Per gestire questa situazione, è possibile ignorare lo Fragment.onHiddenChanged(boolean hidden). Secondo lo documentation, un frammento deve essere sia avviato che visibile (non nascosto), per essere visibile all'utente.

Aggiornamento: Se si utilizza android.support.v4.widget.DrawerLayout, un frammento sotto il cassetto rimane aperto e visibile anche quando il cassetto è aperto. In questo caso è necessario utilizzare DrawerLayout.setDrawerListener() e ascoltare i callback onDrawerClosed() e onDrawerOpened().

+4

'onStop' e' onPause' non vengono chiamati quando un frammento diventa invisibile utilizzando una transazione. Tuttavia 'onHiddenChanged' è chiamato come suggerisce risposta s1rius –

+0

Questo non funziona in NavigationDrawer. onHiddenChanged non viene chiamato sulla libreria di supporto v4/v11. onStart e onResume verranno anche chiamati tutte le volte che si apre la disposizione dei cassetti. – drdrej

+0

@drdrej Il problema è che il cassetto non nasconde completamente i frammenti sotto. Se si utilizza DrawerLayout dalla libreria di supporto, è necessario utilizzare DrawerListener. –

28

fuori-corso è possibile @Overriede seguente metodo per farlo:

@Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 
     if (isVisibleToUser) { 
      // Do your Work 
     } else { 
      // Do your Work 
     } 
    } 
+0

anche per me ha funzionato. .. grazie .. – WonderSoftwares

+0

E si può facilmente sapere se il frammento è visibile all'utente o meno chiamando 'getUserVisibleHint()' – ARiF

+0

setUserVisibleHint funziona con viewpager ma non con il normale contenitore di frammenti. – MikeL

42

ho @Override questo metodo e risolvere il mio problema:

@Override 
public void onHiddenChanged(boolean hidden) { 
    super.onHiddenChanged(hidden); 
    if (hidden) { 
     //do when hidden 
    } else { 
     //do when show 
    } 
} 
+1

Provato a non risolvere ma usando 'setUserVisibleHint' come mostrato in http://stackoverflow.com/a/18375436/1815624 funziona – CrandellWS

0

setUserVisibleHint chiamata prima onCreateView. e non è possibile aggiornare qualsiasi View all'interno setUserVisibleHint Io uso

public void setMenuVisibility(final boolean visible) 

per visibilità e onHiddenChanged() non ha chiamato per la prima volta. chiama quando lo stato nascosto cambia. perché un fragment is visible by default.Al fine di raggiungere questo metodo per la prima volta dovete chiamare mFragmentTransaction.hide(oldFragment) allora funzionerà

Nota

se si desidera utilizzare suggerimento setUserVisible e aggiornamento View Use this method

0

Basta provare questo nella vostra setUserVisibleHint()

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if(isVisibleToUser && getView() != null){ 
     isActive = true; 
     init(); 
    }else if(isVisibleToUser && getView() == null){ 
     isActive = false; 
    }else{ 
     isActive = true; 
    } 
} 

e creare questo codice in onCreateView():

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    if(!isActive){ 
     init(); 
    } 
} 
+0

' isVisibleToUser && getView()! = Null' ha funzionato perfettamente per me! – Annihil

1

provare questo codice:

@Override 
public void setUserVisibleHint(boolean visible) 
{ 
    super.setUserVisibleHint(visible); 
    if (visible && isResumed()) 
    { 
     onResume(); 
    } 
} 

@Override 
public void onResume() 
{ 
    super.onResume(); 
    if (!getUserVisibleHint()) 
    { 
     return; 
    } 

    //Add your code this section 
} 
0

Un altro modo per chiamare il metodo frammento quando frammento è visibile e si utilizza viewpager in attività.

// prima di tutto si crea un'interfaccia

public interface ShowFragmentVisible{ 
     public void showFragment();} 

// Dopo che questa interfaccia implementa all'interno Frammento del genere

 public class MyFragment extends Fragment implements 
     ShowFragmentVisible { 
      @Override 
public void showFragment() { 
} 

// Ora va la vostra attività quindi creare oggetto di Interfaccia e chiamata interna quando addOnViewpagerListener

ShowFragmentVisible showFragmentVisible; 

@Override 
public void onAttachFragment(Fragment fragment) { 
    super.onAttachFragment(fragment); 

    if (fragment instanceof ShowFragmentVisible) { 
     showFragmentVisible = (ShowFragmentVisible) fragment; 
    } 

} 
    //your viewpager method 
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

     } 

     @Override 
     public void onPageSelected(int position) { 
      if (position==0){ 
       showFragmentVisible.showFragment(); 

      } 

     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 

     } 
    }); 


this is another alternative,but its work for me successfully 
Problemi correlati