J'utilise la méthode suivante pour basculer entre les fragments (dans mon NavigationDrawer) en les affichant/les masquant.
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;
}
Ce que je ne sais pas, c'est quelle méthode du cycle de vie de Fragments est appelée quand je le montre ou le cache? (puisqu'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 lors de l'affichage et de la dissimulation d'un certain fragment.
Semblable au cycle de vie d'une activité, Android appelle onStart () lorsque le fragment devient visible. onStop()
est normalement appelé lorsque le fragment devient invisible, mais il peut également être appelé plus tard.
Selon votre mise en page Android peut appeler onStart()
) même lorsque votre fragment n'est pas encore visible, mais qu'il appartient à un conteneur parent visible. Par exemple, ceci est valable pour Android.support.v4.view.ViewPager
Qui vous oblige à remplacer Fragment.setUserVisibleHint()
méthode. Dans tous les cas, si vous devez enregistrer/désenregistrer BroadcastReceivers ou d’autres écouteurs, vous pouvez utiliser en toute sécurité onStart()
et onStop()
méthodes car elles seront appelées toujours.
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 caché), pour être visible à l'utilisateur.
Mise à jour: Si vous utilisez Android.support.v4.widget.DrawerLayout
, Un fragment situé sous le tiroir reste démarré et visible même lorsque le tiroir est ouvert. Dans ce cas, vous devez utiliser DrawerLayout.setDrawerListener()
et écouter les rappels onDrawerClosed()
et onDrawerOpened()
.
Je @ Override 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
}
}
bien sûr, vous pouvez @Overriede suivre la méthode pour le faire:
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Do your Work
} else {
// Do your Work
}
}
Le comportement de pagineur en vue de vue est différent avec le conteneur de fragments régulier.
Essayez ce code:
boolean mIsVisibleToUser;
/**
* is visible to user
*/
public void show() {
//do when show
}
/**
* is invisible to user
*/
public void hide() {
//do when gone
}
@Override
public void onResume() {
super.onResume();
if (!mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = true;
show();
}
}
@Override
public void onPause() {
super.onPause();
if (mIsVisibleToUser && getUserVisibleHint()) {
mIsVisibleToUser = false;
hide();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isResumed()) {
if (mIsVisibleToUser != isVisibleToUser) {
mIsVisibleToUser = isVisibleToUser;
if (isVisibleToUser) show();
else hide();
}
}
}
public boolean isVisibleToUser() {
return mIsVisibleToUser;
}
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();
}
}
Vous pouvez utiliser 'onCreateView' (ou 'onActivityCreated') et 'onHiddenChanged'. Utilisez 'onCreateView' pour la première émission et utilisez 'onHiddenChanged' pour plus tard. 'setMenuVisibility' n'est pas appelé lors du contrôle de transaction.
@Override
public View OnCreateView() {
// fragment will show first
}
@Override
public void onHiddenChanged(boolean hidden) {
if (!hidden) {
// fragment will show
}
else {
// fragment will hide
}
}
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();}
// Ensuite, cette interface est implémentée dans Fragment comme ça
public class MyFragment extends Fragment implements
ShowFragmentVisible {
@Override
public void showFragment() {
}
// va maintenant votre activité puis crée un objet d'interface et appelle à l'intérieur 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
setUserVisibleHint
appel avant onCreateView
. et vous ne pouvez mettre à jour aucune vue à l'intérieur de setUserVisibleHint que j'utilise
public void setMenuVisibility(final boolean visible)
pour visibilité et onHiddenChanged () n'a pas appelé pour la première fois . il appelle quand l'état caché change. parce qu'un fragment is visible by default
. Afin de réaliser cette méthode pour la première fois, vous devez appeler mFragmentTransaction.hide(oldFragment)
puis cela fonctionnera
Remarque
si vous voulez utiliser la directive setUserVisible et mettre à jour la vue Utilisez cette méthode
Bien sûr, vous pouvez remplacer setUserVisibleHint
ou setMenuVisibility
, mais si vous devez accéder à Context
ou Activity
, ils seront nuls! Il y a une autre méthode onStart
qui a toujours le contexte disponible, mais elle ne sera appelée qu'une fois lors de la création d'un fragment et si vous commencez à vous déplacer entre vos fragments dans un pager, vous verrez qu'il ne sera pas obtenu. appelé en deuxième vue et après.
Alors ... que faire maintenant?
La solution de contournement est assez simple, utilisez onStart
pour la première visite et setMenuVisibility
pour les visites suivantes. 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, Context
sera toujours disponible pour la méthode doSth()
.