66

Ho un ViewPager, ogni pagina è una vista Frammento. Voglio verificare se un frammento si trova in una regione visibile. la Fragment.isVisible unico testCome verificare se una vista frammento è visibile all'utente?

  • il frammento è collegato a un'attività
  • il frammento è impostato visibile
  • il frammento è stato aggiunto a una vista

Il ViewPager creerà 3 (per impostazione predefinita) frammento e tutti e tre soddisfano i criteri precedenti, ma solo uno è effettivamente visibile all'utente (gli umani occhi)

+0

si prega di inviare il codice per un migliore aiuto. – Raj

+2

Mi piacerebbe saperlo anche in questo momento. –

risposta

21

Hai ragione, c'è un modo migliore per farlo!

Dai uno sguardo allo FragmentPagerAdapter javadoc online e vedrai che esiste un metodo setPrimaryItem(ViewGroup container, int position, Object object):void che fa esattamente ciò di cui hai bisogno.

Dal javadoc

setPrimaryItem public void (contenitore, int position, oggetto Object ViewGroup)

Chiamato per informare l'adattatore di quale elemento è attualmente considerata il "primario" , questo è l'unico che mostra all'utente la pagina attuale .

Contenitore parametri La vista contenente dalla quale sarà rimossa la pagina . posizione La posizione della pagina che ora è la principale. oggetto Lo stesso oggetto restituito da 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 rapidamente questo viene attivato più volte sulla preparazione del frammento e, mentre l'utente sta scorrendo rapidamente.

quindi potrebbe essere una buona idea di allegare anche una ViewPager.OnPageChangeListener e solo fare ciò che deve essere fatto una volta che i viewpagers scorrere Stato diventa SCOLL_STATE_IDLE di nuovo.

+1

questo approccio funziona alla grande se si estende la classe 'Application' e si deve verificare se una particolare interfaccia utente sta mostrando. Ho appena finito di usare diversi booleani per verificare se l'app fosse in background e se un particolare frammento fosse mostrato. –

2

Se si conosce la "pagina" a cui ciascun frammento è collegato, è possibile utilizzare ViewPager.getCurrentItem() per determinare quale frammento è "visibile".

+4

Questo è quello che sto facendo adesso. Sto solo pensando se ci sono altri modi. Grazie – davidshen84

+0

Hai trovato un altro modo? –

62

Questo è ciò che utilizzo 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"); 
    } 
} 
+0

Questo non funziona come da documentazione: "Imposta un suggerimento al sistema sul fatto se l'interfaccia utente di questo frammento sia attualmente visibile all'utente.Questo suggerimento è impostato su true ed è persistente su stato istanza frammento salva e ripristina" – Edison

+1

Buona soluzione (+1) ma il codice può essere semplificata: \t 'setUserVisibleHint public void (isVisibleToUser booleano) { \t super.setUserVisibleHint (isVisibleToUser); \t m_iAmVisible = falso; // default non visibile \t se (isVisibleToUser) { \t m_iAmVisible = true; \t}} \t ' – PeteH

+2

semplificata: setUserVisibleHint public void (isVisibleToUser booleano) {super.setUserVisibleHint (isVisibleToUser); m_iAmVisible = isVisibleToUser;} – Kasas

9

Per i miei scopi, ha funzionato per utilizzare ViewPager.OnPageChangeListener.onPageSelected() insieme a Fragment.onActivityCreated() per eseguire un'azione quando il frammento è visibile. Fragment.getUserVisibleHint() aiuta anche.

2

Sto usando "setMenuVisibility" -Method per risolvere questo problema. Poiché ogni frammento può avere elementi della barra delle azioni, 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 
    } 
} 
4

Cosa c'è di sbagliato con l'utilizzo di getView().isShown() per scoprire se un frammento è in realtà visibile?

+0

Hai provato la tua idea? Penso che [questo] (http://stackoverflow.com/questions/6796299/view-getvisibility-isshown-return-incorrect-visibility) post abbia messo in evidenza la stessa idea. – davidshen84

+0

Sì. Funziona per me, come suggerito nel post collegato. – awy

+0

Apparentemente, non stiamo parlando dello stesso * problema * di visibilità qui ... – davidshen84

3
isVisible() 

Può ancora restituire true anche se il frammento è dietro un'attività.

sto usando il seguente:

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

nel mio caso, tra l'altro hanno a che 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(); 
     } 
    } 
} 
0

non può setUserVisibleHint probabilmente essere chiamato, onHiddenChanged può essere chiamato non ogni volta che viene chiuso un altro frammento. Pertanto, è possibile fare affidamento su onResume (e), ma in genere viene chiamato troppo spesso (ad esempio, quando si attiva lo schermo di un dispositivo). Inoltre in alcune situazioni non viene chiamato, è necessario gestire il frammento corrente nell'attività dell'host e scrivere:

if (currentFragment != null) { 
    currentFragment.onResume(); 
} 
Problemi correlati