Cycle de vie du fragment – quelle méthode est appelée à afficher / masquer?

J’utilise la méthode suivante pour basculer entre les fragments (dans mon NavigationDrawer) en les affichant / masquant.

protected void showFragment(int container, Fragment fragment, Ssortingng tag, Ssortingng 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; } 

Qu’est-ce que je ne sais pas à propos de quelle méthode du cycle de vie Fragments est appelée quand je la montre ou la cache? (comme il n’y a pas de méthode telle que onShow () ou onHide (), je ne sais pas trop quoi utiliser). Je veux effectuer des actions spécifiques en montrant et en cachant un certain fragment.

Semblable au cycle de vie des activités, Android appelle onStart () lorsque fragment devient visible. onStop() est normalement appelé lorsque fragment devient invisible, mais il peut également être appelé plus tard.

Selon votre mise en page, Android peut même appeler onStart() lorsque votre fragment n’est pas encore visible, mais il appartient à un conteneur parent visible. Par exemple, cela est valable pour android.support.v4.view.ViewPager qui nécessite la substitution de la méthode Fragment.setUserVisibleHint() . Dans tous les cas, si vous devez enregistrer / désenregistrer BroadcastReceivers ou d’autres écouteurs, vous pouvez utiliser en toute sécurité les méthodes onStart() et onStop() , car celles-ci seront toujours appelées.

Remarque: certains conteneurs de fragments peuvent conserver les fragments invisibles démarrés. Pour gérer cette situation, vous pouvez remplacer Fragment.onHiddenChanged(boolean hidden) . Selon la documentation , un fragment doit être à la fois démarré et visible (non masqué) pour être visible par l’utilisateur.

Mise à jour: Si vous utilisez android.support.v4.widget.DrawerLayout un fragment situé sous le tiroir rest ouvert et visible même lorsque le tiroir est ouvert. Dans ce cas, vous devez utiliser DrawerLayout.setDrawerListener() et écouter les onDrawerClosed() et onDrawerOpened() .

J’ai @verride cette méthode et résoudre mon problème:

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

hors-cours, vous pouvez suivre la méthode suivante:

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

Essayez ce code:

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

Essayez ceci dans votre 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; } } 

Et créez ce code dans onCreateView () :

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

setUserVisibleHint appel avant onCreateView . et vous ne pouvez pas mettre à jour une vue dans setUserVisibleHint que j’utilise

 public void setMenuVisibility(final boolean visible) 

pour la visibilité et onHiddenChanged () n’a pas appelé pour la première fois . il appelle quand l’état caché change. car un fragment is visible by default . Pour réaliser cette méthode pour la première fois, vous devez appeler mFragmentTransaction.hide(oldFragment) puis cela fonctionnera.

Remarque

si vous souhaitez utiliser l’indicateur setUserVisible et mettre à jour View Use this method

Une autre façon d’appeler la méthode fragment lorsque fragment est visible et que vous utilisez viewpager en activité.

// tout d’abord vous créez une interface

 public interface ShowFragmentVisible{ public void showFragment();} 

// Après cela, cette interface implémente Fragment comme ça

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

// Va maintenant à ton activité, puis crée un object d’interface et appelle quand 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 

Bien sûr, vous pouvez remplacer setUserVisibleHint ou setMenuVisibility mais si vous devez accéder à Context ou Activity , ils seront nuls là-bas! Il y a une autre méthode onStart qui a toujours le contexte à scope de main, mais elle ne sera appelée qu’une fois lors de la création de fragment et si vous commencez à vous déplacer entre vos fragments dans un pager, vous verrez qu’elle ne sera pas appelée ensuite.

Alors … que faire maintenant?

La solution est assez simple, utilisez onStart pour la première visite et setMenuVisibility pour les setMenuVisibility . Votre code ressemblera probablement à celui ci-dessous:

Classe de fragment:

 public class MyFragmentClass{ private boolean isCurrentVisible = false; ... @Override public void onStart() { super.onStart(); if (isCurrentVisible) doSth(); } @Override public void setMenuVisibility(boolean menuVisible){ super.setMenuVisibility(menuVisible); this.isCurrentVisible = menuVisible; if(menuVisible && getContext() != null) doSth(); } 

De cette façon, le Context sera toujours disponible pour la méthode doSth() .