Android的ListView控件 - 停止滚动,在“整体”行位置 [英] Android ListView - stop scrolling at 'whole' row position

查看:335
本文介绍了Android的ListView控件 - 停止滚动,在“整体”行位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉的混乱冠军,我不能EX preSS的问题​​很简洁...

Sorry for the confusing title, I cannot express the problem very concisely...

我有一个使用圆形/无限适配器,这基本上意味着我可以滚动向上或向下,就像我想,当它到达顶部或底部的项目将环绕一个ListView一个Android应用程序,使它似乎给用户,如果他正在旋转的无限长的列表(〜100)重复项目。

I have an Android app with a ListView that uses a circular / "infinite" adapter, which basically means I can scroll it up or down as much as I want and the items will wrap around when it reaches the top or bottom, making it seem to the user as if he is spinning an infinitely long list of (~100) repeating items.

该设置的关键是让用户选择一个随机的项目,只需通过旋转/扔的ListView和等待,看看它停止。我减少列表视图的摩擦,因此甩了一下速度更快,时间更长,这似乎工作真的很好。最后,我放置一个部分透明图像上的ListView来阻挡的顶部和底部产品(具有从透明到黑色的转变)的顶部,使它看起来好像用户在中间的选择的项目,就好像它们是在一个旋转的车轮,他们被扔控制。

The point of this setup is to let the user select a random item, simply by spinning / flinging the listview and waiting to see where it stops. I decreased the friction of the Listview so it flings a bit faster and longer and this seems to work really nice. Finally I placed a partially transparent image on top of the ListView to block out the top and bottom items (with a transition from transparent to black), making it seem as if the user is "selecting" the item in the middle, as if they were on a rotating "wheel" that they control by flinging.

有一个明显的问题:后扔在ListView不会停止在一个特定的项目,但它可以阻止两个项目(其中第一个可见的产品则仅部分地示出)之间徘徊。我想避免这一点,因为在这种情况下,这不是显而易见哪个项目已被随机选择

There is one obvious problem: after flinging the ListView does not stop at a particular item, but it can stop hovering between two items (where the first visible item is then only partially shown). I want to avoid this because in that case it is not obvious which item has been "randomly selected".

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

Long story short: after the ListView has finished scrolling after flinging, I want it to stop on a "whole" row, instead of on a partially visible row.

现在我实现了这个问题,通过检查,当滚动停止,然后选择第一个可见项目,因为这样的:

Right now I implemented this behavior by checking when the scrolling has stopped, and then selecting the first visible item, as such:

    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跳下几乎一整行(减去这两个像素)。

This works reasonably well, apart from one glaringly obvious problem... The first visible item might only be visible for a pixel or two. In that case, I want the ListView to jump "up" for those two pixels so that the second visible item is selected. Instead, of course, the first visible item is selected which means the ListView jumps "down" almost an entire row (minus those two pixels).

在短期,而不是​​跳到第一个可见项目,我希望它跳到是可见的大部分项目。如果第一个可见的产品不到一半可见,我希望它转移到第二可见项目。

In short, instead of jumping to the first visible item, I want it to jump to the item that is visible the most. If the first visible item is less than half visible, I want it to jump to the second visible item.

下面是希望传达我的观点的例证。最左边的ListView(每对)急张显示后的状态已停止(它在哪里停止),右边的ListView显示它的外观后,作出了跳通过选择第一个可见项目。在左边我显示当前的(错误的)情况:B项只是勉强可见的,但它仍然是第一个可见项目,以便在ListView跳转到选择的项目 - 这是不符合逻辑的,因为它滚动,几乎整个项目的高度到那里。这将是更合理的滚动到C项(这是描绘在右侧),因为这是更近。

Here's an illustration that hopefully conveys my point. The left most ListView (of each pair) shows the state after flinging has stopped (where it comes to a halt), and the right ListView shows how it looks after it made the "jump" by selecting the first visible item. On the left I show the current (wrong) situation: Item B is only barely visible, but it is still the first visible item so the listView jumps to select that item - which is not logical because it has to scroll almost an entire item height to get there. It would be much more logical to scroll to Item C (which is depicted on the right) because that is "closer".

我如何能实现这种行为?我能想到的唯一的办法就是以某种方式衡量第一个可见项目的多少是可见的。如果超过50%,那么我跳转到该位置。如果低于50%,我跳到那个位置+ 1,不过,我不知道如何来衡量?

How can I achieve this behavior? The only way I can think of is to somehow measure how much of the first visible item is visible. If that is more than 50%, then I jump to that position. If it is less than 50%, I jump to that position + 1. However I have no clue how to measure that...

任何想法的?

推荐答案

您可以得到一个孩子使用 getChildVisibleRect 方法可见尺寸。如果你有,你会得到孩子的总高度,您可以滚动到适当的孩子。

You can get the visible dimensions of a child using the getChildVisibleRect method. When you have that, and you get the total height of the child, you can scroll to the appropriate child.

在下面的例子中我检查至少有一半的孩子是否可见:

In the example below I check whether at least half of the child is visible:

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控件 - 停止滚动,在“整体”行位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆