Android ListView - 在 'whole' 行位置停止滚动

标签 android listview scroll

抱歉,标题困惑,我无法非常简洁地表达问题......

我有一个带有 ListView 的 Android 应用程序,它使用圆形/“无限”适配器,这基本上意味着我可以根据需要向上或向下滚动它,当它到达顶部或底部时,项目将环绕,让用户觉得他正在旋转一个无限长的(~100)重复项列表。

此设置的要点是让用户选择一个随机项目,只需旋转/甩动 ListView 并等待查看它停止的位置。我减少了 Listview 的摩擦力,因此它的移动速度更快、时间更长,而且看起来效果很好。最后,我在 ListView 的顶部放置了一个部分透明的图像以遮挡顶部和底部的项目(从透明到黑色的过渡),让用户看起来好像在“选择”中间的项目,就好像他们在他们通过 throw 控制的旋转“轮子”上。

有一个明显的问题:抛出后 ListView 不会停在特定项目上,但它可以停止在两个项目之间悬停(第一个可见项目仅部分显示)。我想避免这种情况,因为在那种情况下,哪个项目是“随机选择”的并不明显。

长话短说:在 ListView 完成滚动后,我希望它停止在“整”行,而不是部分可见的行。

现在我通过检查滚动何时停止然后选择第一个可见项目来实现此行为,如下所示:

    lv = this.getListView();
    
    lv.setFriction(0.005f);
    lv.setOnScrollListener(new OnScrollListener() {
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {}

        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) 
            {
                if (isAutoScrolling) return;
                
                isAutoScrolling = true;
                int pos = lv.getFirstVisiblePosition();
                lv.setSelection(pos);
                isAutoScrolling = false;
            }
        }
    });

除了一个明显的问题外,这工作得相当好......第一个可见项目可能只在一两个像素内可见。在那种情况下,我希望 ListView 针对这两个像素“向上”跳转,以便选择第二个 可见项。相反,当然,第一个可见项目被选中,这意味着 ListView 几乎“向下”跳转整行(减去那两个像素)。

简而言之,我希望它跳转到最可见的项目,而不是跳转到第一个可见项目。如果第一个可见项不到一半可见,我希望它跳转到第二个可见项。

这里有一个插图,希望能传达我的观点。最左边的 ListView(每对)显示了 flinging 停止后的状态(它停止的地方),右边的 ListView 显示了它通过选择第一个可见项目进行“跳跃”后的样子。在左侧,我显示了当前(错误的)情况:项目 B 几乎不可见,但它仍然是第一个可见项目,因此 listView 跳转以选择该项目——这是不合逻辑的,因为它必须滚动几乎整个项目高度到那里。滚动到项目 C(如右图所示)会更合乎逻辑,因为它“更近”。

Image
(来源:nickthissen.nl)

我怎样才能实现这种行为?我能想到的唯一方法是以某种方式衡量第一个可见项目有多少是可见的。如果超过 50%,那么我会跳到那个位置。如果它小于 50%,我会跳到那个位置 + 1。但是我不知道如何测量它......

有什么想法吗?

最佳答案

您可以使用 getChildVisibleRect 方法获取 child 的可见尺寸。当你有了它,并且你得到了 child 的总高度,你可以滚动到合适的 child 。

在下面的示例中,我检查是否至少有一半的 child 可见:

View child = lv.getChildAt (0);    // first visible child
Rect r = new Rect (0, 0, child.getWidth(), child.getHeight());     // set this initially, as required by the docs
double height = child.getHeight () * 1.0;

lv.getChildVisibleRect (child, r, null);

if (Math.abs (r.height ()) < height / 2.0) {
    // show next child
}

else {
    // show this child
}

关于Android ListView - 在 'whole' 行位置停止滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15338509/

相关文章:

javascript - jQuery 的滚动功能无法正常工作

javascript - HTML:动态修复用户正在阅读的标题和副标题在顶部

android - "Gradle Version 2.10 is required."错误

android - 在两行ListView中列出联系信息

java - 如何在ListView的每一行添加按钮?

java - Android Listview 文本对齐

Android 线性布局和可变数量的按钮

android - 如何使用 xml 文件设置爆炸过渡

Android:ListPreference 不支持 int 值

html溢出问题