2012-06-23 6 views
16

¿Cómo sabes si tu ListView tiene suficiente cantidad de elementos para poder desplazarse?¿Cómo comprobar si un ListView tiene una cantidad de elementos desplazables?

Por ejemplo, si tengo 5 artículos en mi ListView toda ella se mostrarán en una sola pantalla. Pero si tengo 7 o más, mi ListView comienza a desplazarse. ¿Cómo sé si mi lista puede desplazarse programáticamente?

+0

¿Por qué necesita saber esto? Después de todo, la respuesta puede cambiar en los cambios de orientación, y la respuesta puede cambiar en función de lo que está en sus filas (diferentes diseños de filas, cambios de altura 'wrap_content' basados ​​en la prosa). ¿Qué estás tratando de lograr? – CommonsWare

+0

5 elementos no pueden desplazarse en hdpi 800x480, pero pueden desplazarse en ldpi 240x320, ¡deje que Android se encargue del desplazamiento por usted! De hecho, el pensamiento de CommonsWare, que pasó por mi mente, quise decir: ¿Por qué querrías hacer esto? – t0mm13b

+0

@CommonsWare, absolutamente lo entiendo. Quiero mostrar un pie de página al final de la actividad. Si el ListView se desplaza, quiero colocar la imagen del pie de página como la vista del pie de página de ListView. De lo contrario, puedo configurar la visibilidad de otro pie de página colocado al final del diseño de la actividad. –

Respuesta

-1

Utilice setOnScrollListener, aplicando la devolución de llamada al OnScrollListener, puede determinar si el desplazamiento se está llevando a cabo utilizando las constantes predefinidas y manejar la situación en consecuencia.

+0

Recibiría una devolución de llamada solo si el evento sucede, ¿no es así? Pero el diseño debe cambiarse incluso antes de que el usuario intente desplazarse por la lista. –

1

No se puede detectar esto antes androide hacer que la pantalla con el listView. Sin embargo, puede detectar absolutamente este post-render.

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

    return true;    
} 

Lo que esto hace es comprobar si el listView ventana visible contiene todos los elementos de vista de lista. Si puede, entonces el listView nunca se desplazará y el getLastVisiblePosition() siempre será igual al número total de elementos en el dataAdapter de la lista.

+0

Hola, gracias. Pero si el último elemento es medio visible en la pantalla, la vista de lista también se desplazará. –

+0

¿Eliminaría la parte "+1" de la respuesta de Diegosan? –

+1

No, esto no hará que su respuesta funcione. Verifique mi respuesta a continuación. –

13

respuesta de Diegosan no puede diferenciar cuando el último artículo es parcialmente visible en la pantalla. Aquí hay una solución a ese problema.

primer lugar, el ListView se debe dejar en la pantalla antes de que podamos comprobar si su contenido es desplazable. Esto se puede hacer con un ViewTreeObserver:

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

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

Y aquí es willMyListScroll():

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

Solución excelente: se debe agregar una verificación nula al método willMyListScroll() para getChildAt (pos). Si la lista está vacía, se bloqueará: D – HelloImKevo

+2

Creo que esto está mal. getChildAt() solo cuenta los niños que están visibles en la pantalla. Mientras tanto, getLastVisiblePosition devuelve el índice basado en el Adaptador. Entonces, si la lastVisiblePosition es 8 porque es el noveno elemento de la lista y solo hay 4 elementos visibles en la pantalla, tendrá un colapso. Verifíquelo llamando a getChildCount() y vea. Los índices de getChildAt no son los mismos que los índices para el conjunto de datos. mira esto: http://stackoverflow.com/questions/6766625/listview-getchildat-returning-null-for-visible-children – jacosta

0

Ésta es la forma en que solía comprobar

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

si da cierto, entonces la lista es por lo la parte inferior

3

Según mi comentario sobre la respuesta de Mike Ortiz', creo que su respuesta es incorrecta:

getChildAt() solo cuenta los elementos secundarios que están visibles en la pantalla. Mientras tanto, getLastVisiblePosition devuelve el índice basado en el Adaptador. Entonces, si la lastVisiblePosition es 8 porque es el noveno elemento de la lista y solo hay 4 elementos visibles en la pantalla, tendrá un colapso. Verifíquelo llamando a getChildCount() y vea. Los índices de getChildAt no son los mismos que los índices para el conjunto de datos. Mira esto: ListView getChildAt returning null for visible children

aquí está mi solución:

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

Esta solución también funcionará incluso después de haber desplazado hasta un punto en la lista o se gira el teléfono. No se limita a una llamada inmediatamente después de la carga inicial de la lista – 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... 
       } 

puede obtener dimensiones en onCreate() llamando al puesto (Ejecutable) en Vista.

+0

utiliza appHeight - 50. ¿Qué es appHeight, cuál es su medida (px, dp, dip ... etc?). Por favor agregue más información. –

1

Este es el código que escribí para mostrar una imagen después de la última fila de la vista de lista:

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 incluye lo siguiente:

/** 
* 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); 

Necesita anular layoutChildren() y utilizarlo dentro de eso:

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