Bekleyin unit1 ListView's smoothScrollToPosition () bitirir

kapsam

Belirli bir konuma düzgünce kaydırmalı ve sonra setSelection (başka bir Konum) ile başka bir konuma "atla" yapmam gerekiyor. Bu, ListView 'de (örneğin) 100 öğenin düzgün kaydırılmasının bir yanılsaması yaratmak için yapılır. smoothScrollToPosition (100) çok fazla sürüyor, biliyorsunuz.

Sorun

setSelection() doesn't wait till smoothScrollToPosition finishes its work, so setSelection() is being called immediately and user sees quick jumping only;

kod

private final int scrollableItems = 20;

int firstVisiblePosition = mListView.getFirstVisiblePosition();
if (firstVisiblePosition < scrollableItems) {
    mListView.smoothScrollToPosition(0);
} else {
    mListView.smoothScrollToPosition(firstVisiblePosition - scrollableItems);
    mListView.setSelection(0);
}
mListView.clearFocus();

Fikir

OK, we could change logic of smoothness illusion: first setSelection(), then scroll smoothly (we're scrolling to the very first item on top of the list):

    int firstVisiblePosition = mListView.getFirstVisiblePosition();

    if (firstVisiblePosition < scrollableItems) {
        mListView.smoothScrollToPosition(0);
    } else {
        mListView.setSelection(scrollableItems);
        mListView.smoothScrollToPosition(0);
    }
    mListView.clearFocus();
15

2 cevap

final ListView listView = ...;
View listItemView = ...;
listView.smoothScrollBy(listItemView.getHeight() * NUMBER_OF_VIEWS, 
    DURATION * 2);
listView.postDelayed(new Runnable() {
    public void run() {
        listView.smoothScrollBy(0, 0);//Stops the listview from overshooting.
        listView.setSelection(0);
    }
}, DURATION);

Tabii ki, kaydırma vb. Yönünün kullanım durumunuz için ayarlanması gerekir (listenin en üstüne git)

EDIT: Old solution could overshoot if the velocity of the scroll was too high, smoothScrollBy(0,0) will stop the smooth scrolling before setting the selection properly and immediately.

24
katma
Evet, sadece uygun bir yüksek hız elde etmek için kullanılır. Yüksekliği * NUMBER_OF_VIEWS diğer uygun büyüklükte bir değerle değiştirdiğiniz sürece (örn. Görünümleriniz çok çeşitlidir), kullanıcının RunSelection (0) ile Runnable'a eklediğinizde fark edemeyeceği yeterince hızlı bir kaydırma elde edeceksiniz. ListView'e postDelayed.
katma yazar Jens, kaynak
Cevap için teşekkürler!
katma yazar Aleksey Malevaniy, kaynak
Ancak sadece sabit yükseklikteki öğeler için bir çözüm olabilir. Ben mListView.setSelection (scrollableItems) olduğunu düşünüyorum; mListView.smoothScrollToPosition (0); hala daha tercih edilir bir yoldur;)
katma yazar Aleksey Malevaniy, kaynak

Başka bir yol OnScrollListener eklemek.

private final int scrollableItems = 20;

int firstVisiblePosition = mListView.getFirstVisiblePosition();
if (firstVisiblePosition < scrollableItems) {
    mListView.smoothScrollToPosition(0);
} else {

    mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(AbsListView absListView, int i) {
        if (i == SCROLL_STATE_IDLE) {
          mListView.setSelection(0);
           }
      }
   })

   mListView.smoothScrollToPosition(firstVisiblePosition - scrollableItems);
}
mListView.clearFocus();
0
katma