web-dev-qa-db-fra.com

Comment tester si une vue fragmentée est visible pour l'utilisateur?

J'ai un ViewPager, chaque page est une vue fragmentée. Je veux tester si un fragment est dans une région visible. le seul test Fragment.isVisible

  • le fragment est attaché à une activité
  • le fragment est mis à visible
  • le fragment a été ajouté à une vue

ViewPager crée 3 fragments (par défaut) et les trois répondent aux critères ci-dessus, mais un seul est réellement visible pour l'utilisateur (l'homme les yeux ).

68
David S.

Tu as raison, il y a une meilleure façon de faire ça! 

Jetez un coup d'oeil à FragmentPagerAdapter javadoc en ligne et vous verrez qu'il existe une méthode setPrimaryItem (conteneur ViewGroup, position int, objet Object): void fait exactement ce dont vous avez besoin.

Du javadoc

public void setPrimaryItem (conteneur ViewGroup, int position, objet object)

Appelé pour informer l'adaptateur de l'élément actuellement considéré. être le "primaire", c'est-à-dire celui qui est présenté à l'utilisateur sous le nom actuel page.

Liste de paramètres container La vue contenant à partir de laquelle la page sera enlevé. position La position de la page qui est maintenant le primaire . object Le même objet qui a été renvoyé par instantiateItem (View, int).

Note sur l'état de défilement

Maintenant, si vous implémentez cela et commencez à déboguer pour avoir une idée du moment exact où cela s'appelle, vous remarquerez rapidement que cela est déclenché plusieurs fois lors de la préparation du fragment et pendant que l'utilisateur glisse dessus. 

Il pourrait donc être judicieux de joindre également un ViewPager.OnPageChangeListener et de ne faire que ce qui doit être fait une fois que l'état de défilement des viewpagers devient SCOLL_STATE_IDLE .

20
hcpl

C'est ce que j'utilise pour déterminer la visibilité d'un fragment.

private static boolean m_iAmVisible;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser);
    m_iAmVisible = isVisibleToUser;

    if (m_iAmVisible) { 
        Log.d(localTAG, "this fragment is now visible");
    } else {  
        Log.d(localTAG, "this fragment is now invisible");
    }
}
65
miroslavign

Pour les besoins de mon propos, il était utile d’utiliser ViewPager.OnPageChangeListener.onPageSelected() avec Fragment.onActivityCreated() pour effectuer une action lorsque le fragment est visible. Fragment.getUserVisibleHint() aide aussi.

9
Leo Landau

J'utilise la méthode "setMenuVisibility" pour résoudre ce problème. Comme chaque fragment peut avoir des éléments de barre d’action, c’est la partie où vous pouvez déterminer quel fragment est actuellement visible pour l’utilisateur.

@Override
public void setMenuVisibility(final boolean visible) {
    super.setMenuVisibility(visible);
    if (!visible) {
        //not visible anymore
    }else{
        yay visible to the user
    }
}
3
Frame91
isVisible() 

Peut toujours retourner vrai même si le fragment est derrière une activité.

J'utilise les éléments suivants:

if (getView() != null && getView().isShown()) {
//your code here
}
3
Peter File

Quel est le problème avec l'utilisation de getView().isShown() pour savoir si un fragment est réellement visible?

3
awy

Si vous savez à quelle "page" chaque fragment est attaché, vous pouvez utiliser ViewPager.getCurrentItem () pour déterminer quel fragment est "visible".

2
roflharrison

setUserVisibleHint ne peut probablement pas être appelé, onHiddenChanged ne peut pas être appelé à chaque fois qu'un autre fragment est en cours de fermeture. Donc, vous pouvez vous fier à onResume (et onPause), mais elle est généralement appelée trop souvent (par exemple, lorsque vous activez l'écran d'un périphérique). De plus, dans certaines situations, il n'est pas appelé, vous devez gérer le fragment actuel de l'activité de l'hôte et écrire:

if (currentFragment != null) {
    currentFragment.onResume();
}
0
CoolMind

Dans mon cas, je dois travailler sur le premier fragment lorsque celui-ci est visible pour l'utilisateur.

 @Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);


    if(viewPager.getAdapter() instanceof YourPager)
    {
        Fragment fragemnt=((YourPager)viewPager.getAdapter()).getFragment(0); //getFragment(int index) custom method
        if( fragemnt instanceof YourFragment)
        {
            ((YourFragment)fragemnt).methodWhochShouldBeCalledAfterUIVisible();
        }
    }
}
0
W00di

Kotlin:

if (userVisibleHint) {
    // the fragment is visible
} else {
    // the fragment is not visible
}

Java

if (getUserVisibleHint()) {
    // the fragment is visible
} else {
    // the fragment is not visible
}

https://developer.Android.com/reference/Android/app/Fragment.html#getUserVisibleHint ()

https://stackoverflow.com/a/12523627/2069407

0
s-hunter