Come verificare se una vista frammento è visibile all'utente?
-
27-10-2019 - |
Domanda
Ho un ViewPager, ogni pagina è una vista Fragment. Voglio testare se un frammento si trova in una regione visibile. l'unico test Fragment.isVisible
- il frammento è collegato a un'attività
- il frammento è impostato visibile
- il frammento è stato aggiunto a una vista ??li>
Il ViewPager creerà 3 (di default) frammento e tutti e tre di esse soddisfano i criteri di cui sopra, ma solo uno è effettivamente visibile all'utente (umano occhi )
Soluzione
Hai ragione c'è un modo migliore per fare questo!
Date un'occhiata alla FragmentPagerAdapter javadoc in linea e vedrete c'è un metodo setPrimaryItem (contenitore ViewGroup, int position, oggetto Object):. vuoto facendo esattamente quello che ti serve
Dal javadoc
setPrimaryItem public void (contenitore ViewGroup, int position, oggetto Object)
Chiamato per informare l'adattatore di cui voce è attualmente considerata tramite il "primario", cioè quella mostra all'utente come l'attuale pagina.
Parametri contenitore La contenente vista da cui la pagina sarà rimosso. posizionare la posizione della pagina che è ora il primario. oggetto Lo stesso oggetto che è stato restituito dal instantiateItem (View, int).
Nota sullo stato di scorrimento
Ora, se si implementa questa e iniziare il debug per avere un'idea di quando esattamente questo è chiamato noterete subito più volte questo viene attivato sulla preparazione del frammento e mentre l'utente sta scorrendo lungo.
Quindi potrebbe essere una buona idea anche allegare un ViewPager.OnPageChangeListener e solo fare ciò che deve essere fatto una volta che i viewpagers scorrimento stato diventa SCOLL_STATE_IDLE di nuovo.
Altri suggerimenti
Questo è quello che uso per determinare la visibilità di un frammento.
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");
}
}
Per i miei scopi, ha funzionato da utilizzare in combinazione con ViewPager.OnPageChangeListener.onPageSelected()
Fragment.onActivityCreated()
per eseguire un'azione quando il frammento è visibile. Fragment.getUserVisibleHint()
aiuta anche.
sto usando "setMenuVisibility" -Metodo per la risoluzione di questo problema. Come ogni frammento può avere ActionBar-voci questa è la parte in cui è possibile determinare quale frammento è attualmente visibile all'utente.
@Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (!visible) {
//not visible anymore
}else{
yay visible to the user
}
}
Cosa c'è di sbagliato con l'utilizzo di getView().isShown()
per scoprire se un frammento è in realtà visibile?
isVisible()
può ancora tornare vero anche se il frammento è dietro un'attività.
sto usando il seguente:
if (getView() != null && getView().isShown()) {
//your code here
}
Se si sa che cosa "pagina" ogni frammento è attaccato si potrebbe usare ViewPager.getCurrentItem () per determinare quali frammento è "visibile".
Nel mio caso ho un devo fare un certo lavoro sul primo frammento quando il frammento è visibile all'utente
@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();
}
}
}
setUserVisibleHint
probabilmente non può essere chiamato, onHiddenChanged
potrebbe non essere chiamato ogni volta quando un altro frammento viene chiuso. Quindi, si può contare su onResume
(e onPause
), ma di solito è chiamato troppo spesso (ad esempio, quando si accende uno schermo del dispositivo). Anche in alcune situazioni non si chiama, si dovrebbe gestire frammento attuale in attività di accoglienza e di scrittura:
if (currentFragment != null) {
currentFragment.onResume();
}
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 ()