2010-03-03 22 views
7

Quiero desplazarme por a ListView en Android por número de píxeles. Por ejemplo, quiero desplazar la lista 10 píxeles hacia abajo (para que el primer elemento de la lista tenga ocultos los 10 píxeles superiores).Desplazarse por ListView por píxeles en Android

pensé que el obviamente visibles scrollBy o scrollTo métodos en ListView haría el trabajo, pero no es así, sino que recorra toda la lista erróneamente (De hecho, el getScrollY siempre devuelven cero a pesar de que se haya desplazado la lista utilizando mi dedo.)

Lo que estoy haciendo es capturar eventos de Trackball y quiero desplazar la vista de lista suavemente de acuerdo con el movimiento de la bola de seguimiento.

+0

Esto es lo que 'scrollby' se supone que debe hacer. ¿Podrías publicar tu código Java? –

+1

Creo que scrollBy enreda de alguna manera el ListView. He estado experimentando con eso también. mueve los eventos táctiles por la cantidad de scrollBy ... así que si configuras y el desplazamiento por 10, por ejemplo, el siguiente evento táctil de la lista estará en el mercado a 10 píxeles por debajo de la ubicación táctil real ..lo siento, no sé de una mejor manera, pero tal vez hay una forma de compensar esto con el método onTouch en listView. – DArkO

Respuesta

10

La forma compatible de desplazarse de un widget ListView es:

mListView.smoothScrollToPosition(position);

http://developer.android.com/reference/android/widget/AbsListView.html#smoothScrollToPosition(int)

Sin embargo ya que ha mencionado específicamente que le gustaría para compensar la vista vertical, debe llamar:

mListView.setSelectionFromTop(position, yOffset);

http://developer.android.com/reference/android/widget/ListView.html#setSelectionFromTop(int,%20int)

Tenga en cuenta que también puede utilizar smoothScrollByOffset(yOffset). Sin embargo, sólo es compatible con la API> = 11

http://developer.android.com/reference/android/widget/ListView.html#smoothScrollByOffset(int)

+0

Además, smoothScroolToPosition solo es API> = 8 :( –

+1

+1 para 'setSelectionFromTop' –

3

Aquí hay un código de mi ListView subclase. Se puede adaptar fácilmente para que pueda usarse en el código de actividad.

getListItemsHeight() devuelve la altura total de píxeles de la lista, y rellena una matriz con compensaciones de píxeles verticales de cada elemento. Si bien esta información es válida, getListScrollY() devuelve la posición actual de desplazamiento vertical de píxeles, y scrollListToY() desplaza la lista a la posición de píxel. Si el tamaño o el contenido de la lista cambia, getListItemsHeight() se debe volver a llamar.

private int m_nItemCount; 
private int[] m_nItemOffY; 

private int getListItemsHeight() 
{ 
    ListAdapter adapter = getAdapter(); 
    m_nItemCount = adapter.getCount(); 
    int height = 0; 
    int i; 

    m_nItemOffY = new int[m_nItemCount]; 

    for(i = 0; i< m_nItemCount; ++i){ 
     View view = adapter.getView(i, null, this); 

     view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 

     m_nItemOffY[i] = height; 
     height += view.getMeasuredHeight(); 
    } 

    return height; 
} 

private int getListScrollY() 
{ 
    int pos, nScrollY, nItemY; 
    View view; 

    pos = getFirstVisiblePosition(); 
    view = getChildAt(0); 
    nItemY = view.getTop(); 
    nScrollY = m_nItemOffY[pos] - nItemY; 

    return nScrollY; 
} 

private void scrollListToY(int nScrollY) 
{ 
    int i, off; 

    for(i = 0; i < m_nItemCount; ++i){ 
     off = m_nItemOffY[i] - nScrollY; 
     if(off >= 0){ 
      setSelectionFromTop(i, off); 
      break; 
     } 
    } 
} 
10

Si nos fijamos en la fuente para el método scrollListBy() añadido en api 19 se verá que se puede utilizar el paquete de ámbito trackMotionScroll método.

public class FutureListView { 

    private final ListView mView; 

    public FutureListView(ListView view) { 
     mView = view; 
    } 

    /** 
    * Scrolls the list items within the view by a specified number of pixels. 
    * 
    * @param y the amount of pixels to scroll by vertically 
    */ 
    public void scrollListBy(int y) { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
      mView.scrollListBy(y); 
     } else { 
      // scrollListBy just calls trackMotionScroll 
      trackMotionScroll(-y, -y); 
     } 
    } 

    private void trackMotionScroll(int deltaY, int incrementalDeltaY) { 
     try { 
      Method method = AbsListView.class.getDeclaredMethod("trackMotionScroll", int.class, int.class); 
      method.setAccessible(true); 
      method.invoke(mView, deltaY, incrementalDeltaY); 
     } catch (Exception ex) { 
      throw new RuntimeException(ex); 
     }; 
    } 
} 
+0

Asegúrese de que la aceleración de hardware esté activada. Http://developer.android.com/guide/topics/graphics/hardware-accel.html – enl8enmentnow

+0

Usted De nada, me alegro de que haya sido útil. – enl8enmentnow

0

si desea mover por píxeles entonces u puede utilizar este

public void scrollBy(ListView l, int px){ 
    l.setSelectionFromTop(l.getFirstVisiblePosition(),l.getChildAt(0).getTop() - px); 
} 

esto funciona incluso para los que tienen cabeceras masivas

1

por ahora, ListViewCompat es probablemente una mejor solución.

android.support.v4.widget.ListViewCompat.scrollListBy(@NonNull ListView listView, int y) 
Cuestiones relacionadas