等到 ListView smoothScrollToPosition() 完成

Posted

技术标签:

【中文标题】等到 ListView smoothScrollToPosition() 完成【英文标题】:Wait unitl ListView's smoothScrollToPosition() finishes 【发布时间】: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();

【问题讨论】:

【参考方案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();

【讨论】:

以上是关于等到 ListView smoothScrollToPosition() 完成的主要内容,如果未能解决你的问题,请参考以下文章

VS 2008 (C#) 使用Winform方式,控件Listview要等数据全部加载完后才显示,有啥办法边加载边显示?

Puppeteer:我怎样才能等到列表关闭?如何等到元素从 DOM 中消失?

puppeteer:如何等到元素可见?

使函数等到元素存在

等到页面加载 Selenium Python

Python 弹出命令。等到命令完成