2012-06-23 1 views
16

Come fai a sapere se il tuo ListView ha un numero sufficiente di elementi in modo che possa scorrere?Come verificare se un mio ListView ha un numero scorrevole di elementi?

Ad esempio, se ho 5 elementi sul mio ListView tutto verrà visualizzato su una singola schermata. Ma se ho 7 o più, il mio ListView inizia a scorrere. Come faccio a sapere se la mia lista può scorrere a livello di codice?

+0

Perché hai bisogno di sapere questo? Dopotutto, la risposta potrebbe cambiare in base ai cambiamenti di orientamento e la risposta potrebbe cambiare in base a ciò che è nelle tue righe (layout di righe differenti, modifiche di altezza di 'wrap_content' basate sulla prosa). Cosa stai cercando di ottenere? – CommonsWare

+0

5 elementi non possono scorrere su hdpi 800x480, ma possono scorrere su ldpi 240x320, lasciare che Android si occupi dello scorrimento per te! In effetti, il pensiero di CommonsWare, che mi passava per la mente, significava: - Perché vorresti farlo? – t0mm13b

+0

@CommonsWare, assolutamente lo capisco. Voglio mostrare un footer in fondo all'attività. Se ScrollView List si desidera posizionare l'immagine footer come visualizzazione footer di ListView. Altrimenti posso impostare la visibilità di un altro piè di pagina posto alla fine del layout dell'attività. –

risposta

-1

Utilizzare lo setOnScrollListener, applicando la richiamata a OnScrollListener, è possibile determinare se lo scorrimento è in atto utilizzando le costanti predefinite e gestire la situazione di conseguenza.

+0

Riceverò una richiamata solo se l'evento si verifica, no? Ma il layout deve essere modificato anche prima che l'utente tenti di scorrere l'elenco. –

1

Non è possibile rilevare questo prima Android renderizzare lo schermo con il listView. Tuttavia, puoi assolutamente rilevare questo post-rendering.

boolean willMyListScroll() {   
    if(listView.getLastVisiblePosition() + 1 == listView.getCount()) { 
     return false; 
    } 

    return true;    
} 

Quello che fa è controllare se la finestra visibile listView contiene tutti i tuoi oggetti visualizzazione elenco. Se possibile, lo listView non scorrerà mai e il numero getLastVisiblePosition() sarà sempre uguale al numero totale di elementi nel DataAdapter dell'elenco.

+0

Ciao, grazie. Ma se l'ultimo oggetto è visibile a metà sullo schermo, anche la vista elenco scorrerà. –

+0

Rimuovere la parte "+1" della risposta di Diegosan funziona? –

+1

No, questo non farà funzionare la sua risposta. Controlla la mia risposta qui sotto. –

13

La risposta di diegosan non può distinguere quando l'ultimo elemento è parzialmente visibile sullo schermo. Ecco una soluzione a questo problema.

Prima di tutto, è necessario eseguire il rendering di ListView sullo schermo prima di poter verificare se il suo contenuto è scorrevole. Questo può essere fatto con un ViewTreeObserver:

ViewTreeObserver observer = listView.getViewTreeObserver(); 
    observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

     @Override 
     public void onGlobalLayout() { 
      if (willMyListScroll()) { 
       // Do something 
      } 
     } 
    }); 

Ed ecco willMyListScroll():

boolean willMyListScroll() { 
    int pos = listView.getLastVisiblePosition(); 
    if (listView.getChildAt(pos).getBottom() > listView.getHeight()) { 
     return true; 
    } else { 
     return false; 
    } 
} 
+2

Soluzione eccellente: è necessario aggiungere un controllo null al metodo willMyListScroll() per getChildAt (pos). Se la lista è vuota, si bloccherà: D – HelloImKevo

+2

Credo che questo sia sbagliato. getChildAt() conta solo i bambini che sono visibili sullo schermo. Nel frattempo, getLastVisiblePosition restituisce l'indice in base all'adapter. Quindi se l'ultima posizione visibile è 8 perché è il nono elemento nell'elenco e ci sono solo 4 elementi visibili sullo schermo, si verificherà un arresto anomalo. Verificare chiamando getChildCount() e vedere. Gli indici per getChildAt non sono gli stessi degli indici per il set di dati. Controlla questo: http://stackoverflow.com/questions/6766625/listview-getchildat-returning-null-for-visible-children – jacosta

0

Questo è il modo che ho usato per controllare

if (listView.getAdapter() != null 
        && listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 
        && listView.getChildAt(listView.getChildCount() - 1).getBottom() == listView.getBottom()) 

se dà vero, allora la lista è a il fondo

3

Come da mio commento sulla risposta di Mike Ortiz, credo che la sua risposta sia sbagliata:

getChildAt() conta solo i bambini che sono visibili sullo schermo. Nel frattempo, getLastVisiblePosition restituisce l'indice in base all'adapter. Quindi se l'ultima posizione visibile è 8 perché è il nono elemento nell'elenco e ci sono solo 4 elementi visibili sullo schermo, si verificherà un arresto anomalo. Verificalo chiamando getChildCount() e vedi. Gli indici per getChildAt non sono gli stessi degli indici per il set di dati. Check this out: ListView getChildAt returning null for visible children

Ecco la mia soluzione:

public boolean isScrollable() { 
     int last = listView.getChildCount()-1; //last visible listitem view 
     if (listView.getChildAt(last).getBottom()>listView.getHeight() || listView.getChildAt(0).getTop()<0) { //either the first visible list item is cutoff or the last is cutoff 
       return true; 
     } 
     else{ 
      if (listView.getChildCount()==listView.getCount()) { //all visible listitem views are all the items there are (nowhere to scroll) 
       return false; 
      } 
      else{ //no listitem views are cut off but there are other listitem views to scroll to 
       return true; 
      } 
     } 
    } 
+0

Questa soluzione funzionerà anche dopo averlo spostato su un punto dell'elenco o ruotato il telefono. Non è limitato a una chiamata subito dopo il caricamento iniziale dell'elenco – jacosta

-2
boolean listBiggerThanWindow = appHeight - 50 <= mListView.getHeight(); 

      Toast.makeText(HomeActivity.this, "list view bigger that window? " + listBiggerThanWindow, Toast.LENGTH_LONG) 
        .show(); 

      if (listBiggerThanWindow) { 
       // do your thing here... 
       } 

è possibile ottenere dimensioni in onCreate() chiamando posta (Runnable) su View.

+0

si utilizza appHeight - 50. Che cos'è appHeight, qual è la sua misura (px, dp, dip .. ecc.). Si prega di aggiungere ulteriori informazioni. –

1

Questo è il codice che ho scritto per la visualizzazione di un'immagine dopo l'ultima riga della listview:

public class ShowTheEndListview 
{ 
    private ImageView the_end_view; 
    private TabbedFragRootLayout main_layout; 
    private ListView listView; 
    private float pas; 
    private float the_end_img_height; 
    private int has_scroll = -1; 

    public ShowTheEndListview(float height) 
    { 
     the_end_img_height = height; 
     pas = 100/the_end_img_height; 
    } 

    public void setData(ImageView the_end_view, TabbedFragRootLayout main_layout, ListView listView) 
    { 
     this.the_end_view = the_end_view; 
     this.main_layout = main_layout; 
     this.listView = listView; 
    } 

    public void onScroll(int totalItemCount) 
    { 
     if(totalItemCount - 1 == listView.getLastVisiblePosition()) 
     { 
      int pos = totalItemCount - listView.getFirstVisiblePosition() - 1; 
      View last_item = listView.getChildAt(pos); 

      if (last_item != null) 
      { 
       if(listHasScroll(last_item)) 
       { 
//      Log.e(TAG, "listHasScroll TRUE"); 
       } 
       else 
       { 
//      Log.e(TAG, "listHasScroll FALSE"); 
       } 
      } 
     } 
    } 

    private boolean listHasScroll(View last_item) 
    { 
     if(-1 == has_scroll) 
     { 
      has_scroll = last_item.getBottom() > (main_layout.getBottom() - the_end_img_height - 5) ? 1 : 0; 
     } 

     return has_scroll == 1; 
    } 

    public void resetHasScroll() 
    { 
     has_scroll = -1; 
    } 
} 
1

AbsListView comprende questo:

/** 
* Check if the items in the list can be scrolled in a certain direction. 
* 
* @param direction Negative to check scrolling up, positive to check scrolling down. 
* @return true if the list can be scrolled in the specified direction, false otherwise. 
* @see #scrollListBy(int) 
*/ 
public boolean canScrollList(int direction); 

È necessario eseguire l'override layoutChildren() e usarlo all'interno di questo:

@Override 
protected void layoutChildren() { 
    super.layoutChildren(); 
    isAtBottom = !canScrollList(1); 
    isAtTop = !canScrollList(-1); 
}