2010-01-01 21 views
25

¿Hay alguna manera de asegurarme de que un elemento determinado en una vista de lista de Android sea completamente visible?asegurar visible en android listview?

Me gustaría poder desplazarme programáticamente a un elemento específico, como cuando presiono un botón, por ejemplo.

Respuesta

20

ListView.setSelection() desplazará la lista para que el elemento deseado se encuentre dentro de la ventana gráfica.

+4

Setselection lo desplaza a la parte superior de la vista. Solo necesito que se mueva lo menos posible – CodeFusionMobile

+0

Esta respuesta no es precisa, como señaló CodeFusionMobile. Por lo tanto, no lo aceptaría realmente ... :-( – Zordid

11

Práctica:

public static void ensureVisible(ListView listView, int pos) 
{ 
    if (listView == null) 
    { 
     return; 
    } 

    if(pos < 0 || pos >= listView.getCount()) 
    { 
     return; 
    } 

    int first = listView.getFirstVisiblePosition(); 
    int last = listView.getLastVisiblePosition(); 

    if (pos < first) 
    { 
     listView.setSelection(pos); 
     return; 
    } 

    if (pos >= last) 
    { 
     listView.setSelection(1 + pos - (last - first)); 
     return; 
    } 
} 
+6

listView.smoothScrollToPosition (pos); en lugar de setSelection (...) si lo desea. Gracias jauseg. – Saikat

+0

+1 ¡gracias por esto! – Olayinka

+0

Hmm. al menos una trampa aquí: en caso de que configure la selección antes de que se haya realizado el diseño, no habrá una última posición visible (= -1) y todo se rompe. Debe asegurarse de que esto se ejecute DESPUÉS de que el diseño esté listo. De lo contrario, lo hace no funciona como se esperaba, pero establece la selección completamente incorrecta. – Zordid

2

Tengo una solución más corta y, en mi opinión, mejor para hacer esto: el método ListView requestChildRectangleOnScreen está diseñado para ello.

La respuesta anterior asegura que el elemento se mostrará, pero a veces se mostrará en parte (es decir, cuando se encuentre en la parte inferior de la pantalla). El código siguiente se asegura de que todo el elemento se mostrará y que la vista se desplazará sólo la zona necesaria:

private void ensureVisible(ListView parent, View view) { 
    Rect rect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); 
    parent.requestChildRectangleOnScreen(view, rect, false); 
} 
+7

Si usa API 8 o posterior, el método ListView smoothScrollToPosition() es incluso la solución más inteligente. –

+0

El problema con Yves 'la respuesta es que esta' Vista 'no existe necesariamente ... si no es visible, 'ListView' probablemente lo habrá descartado. De hecho,' smoothScrollToPosition' es la buena aquí nswer. – RedGlyph

3

Recientemente me encontré con el mismo problema, pegue mi solución aquí en caso de que alguien lo necesita (yo estaba tratando de hacer visible por completo el último elemento visible):

if (mListView != null) { 
     int firstVisible = mListView.getFirstVisiblePosition() 
       - mListView.getHeaderViewsCount(); 
     int lastVisible = mListView.getLastVisiblePosition() 
       - mListView.getHeaderViewsCount(); 

     View child = mListView.getChildAt(lastVisible 
       - firstVisible); 
     int offset = child.getTop() + child.getMeasuredHeight() 
       - mListView.getMeasuredHeight(); 
     if (offset > 0) { 
      mListView.smoothScrollBy(offset, 200); 
     } 
    } 
+0

¡Funciona muy bien! Aunque debería mencionar un caso extremo que requiere un cambio de código: debe llamar a mListView.post (nuevo Runnable() {public void run() {(el código anterior);})}); Esto maneja el caso en el que está modificando la altura del último niño (lo que hace que el contenido de ListView sea más alto). Al publicar un archivo ejecutable, ListView tiene la posibilidad de actualizarse antes de intentar desplazarse al final de la lista. – foo64

+1

Lamentablemente, hay un límite interno para la cantidad que 'ListView.smoothScrollBy' desplazará. Eso es porque internamente simula una aventura de usuario. El uso de este método para desplazarse por 10 pantallas con valor de elementos da como resultado desplazarse solo unas pocas pantallas. – foo64