2010-03-03 3 views
7

Я хочу прокрутить a ListView в Android по количеству пикселей. Например, я хочу прокрутить список на 10 пикселей вниз (так, чтобы первый элемент в списке спрятал первые 10 пикселов).Прокрутите списокView по пикселям в Android

Я думал, что, очевидно, видимых scrollBy или scrollTo методы ListView будет делать эту работу, но они не делают, вместо этого они прокручивать весь список неправильно (На самом деле, getScrollY всегда возвращают нулевое значение, даже если я прокручивается список с помощью мой палец.)

То, что я делаю, это захват событий трекбола, и я хочу плавно прокручивать список в соответствии с движением трекбола.

+0

Это то, что должно делать 'scrollby'. Не могли бы вы разместить свой Java-код? –

+1

Я думаю, scrollBy как-то беспорядок listView. Я тоже экспериментировал с этим. он перемещает события касания на величину scrollBy .... так что если вы установите прокрутку y на 10, например, следующее событие касания в списке будет на 10 пикселей ниже места расположения актуала.извините, я не знаю лучшего способа, но, возможно, есть способ компенсировать это с помощью метода onTouch в listView. – DArkO

ответ

10

Поддерживаемый способ прокрутки ListView виджета:

mListView.smoothScrollToPosition(position);

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

Однако, так как вы упомянули, в частности, что вы хотели бы, чтобы компенсировать вид вертикально, вы должны вызвать:

mListView.setSelectionFromTop(position, yOffset);

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

Обратите внимание, что вы также можете использовать smoothScrollByOffset(yOffset). Однако он поддерживается только на API> = 11

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

+0

Кроме того, smoothScroolToPosition - это только API> = 8 :( –

+1

+1 для 'setSelectionFromTop' –

3

Вот код из моего ListView подкласса. Его можно легко адаптировать, чтобы он мог использоваться в коде действия.

getListItemsHeight() возвращает общую высоту пикселя списка и заполняет массив вертикальными смещениями пикселей каждого элемента. Хотя эта информация действительна, getListScrollY() возвращает текущую позицию прокрутки вертикального пикселя, а scrollListToY() прокручивает список до положения пикселя. Если изменяется размер или содержание списка, необходимо снова позвонить getListItemsHeight().

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

Если вы посмотрите на исходный код для метода scrollListBy() добавлен в апи 19 вы увидите, что вы можете использовать пакет trackMotionScroll область действия метода.

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

Убедитесь, что аппаратное ускорение включено. Http://developer.android.com/guide/topics/graphics/hardware-accel.html – enl8enmentnow

+0

Вы Добро пожаловать, рад, что это было полезно. – enl8enmentnow

0

, если вы хотите переместить пикселями, то и может использовать этот

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

это работает для чётных с массивными заголовками

1

сейчас, ListViewCompat, вероятно, является лучшим решением.

android.support.v4.widget.ListViewCompat.scrollListBy(@NonNull ListView listView, int y) 
Смежные вопросы