【问题标题】:Wait unitl ListView's smoothScrollToPosition() finishes等到 ListView smoothScrollToPosition() 完成
【发布时间】:2011-12-17 05:56:30
【问题描述】:

范围

我需要平滑滚动到某个位置,然后用setSelection(anotherPosition)“跳转”到另一个位置。这样做是为了创建平滑滚动的错觉(例如)ListView 中的 100 个项目。 smoothScrollToPosition(100) 持续时间太长了,你知道的。

问题

setSelection() 不会等到smoothScrollToPosition 完成它的工作,所以会立即调用setSelection(),而用户只会看到快速跳转;

代码

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();

想法

好的,我们可以改变平滑错觉的逻辑:首先setSelection(),然后平滑滚动(我们正在滚动到列表顶部的第一项):

    int firstVisiblePosition = mListView.getFirstVisiblePosition();

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

【问题讨论】:

    标签: android listview smooth-scrolling


    【解决方案1】:
    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);
    

    当然,滚动方向等需要根据您的用例进行调整(转到列表顶部)

    编辑:如果滚动速度太高,旧解决方案可能会过冲,smoothScrollBy(0,0) 将在正确设置选择之前立即停止平滑滚动。

    【讨论】:

    • 但这可能是仅适用于具有固定高度项目的列表的解决方案。我认为 mListView.setSelection(scrollableItems); mListView.smoothScrollToPosition(0);还是更可取的方式;)
    • 是的,它仅用于获得适当的高速。只要您将 height * NUMBER_OF_VIEWS 替换为任何其他适当大的值(即,如果您的视图大小变化很大),您将获得足够快的滚动,当您在 Runnable 中使用 setSelection(0) 捕捉时用户不会注意到是 postDelayed 到 ListView。
    【解决方案2】:

    另一种方法是添加一个 OnScrollListener。

    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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多