Android 停止ListView滚动动画

Android 停止ListView滚动动画,android,listview,scroll,android-listview,Android,Listview,Scroll,Android Listview,我有一个列表视图,大约有100个条目。当用户从下到上进行“投掷”时,它开始滚动并继续滚动,即使手指不再触摸显示器 有没有办法在此时停止滚动动画?当然有办法。但在我看来,问题更在于这样做是否明智 该列表是一个标准的Android控件,在所有应用程序中都能正常运行。因此,如果我在应用程序中发现一个行为不一样的列表,我会感到惊讶。你可以随时把手指放回屏幕上,停止这种放纵 这就是说,如果您想做额外的工作,您可以对列表视图进行子类化,并覆盖其on-touch方法。知道该做什么的最好方法是获取ListVie

我有一个
列表视图
,大约有100个条目。当用户从下到上进行“投掷”时,它开始滚动并继续滚动,即使手指不再触摸显示器


有没有办法在此时停止滚动动画?

当然有办法。但在我看来,问题更在于这样做是否明智

该列表是一个标准的Android控件,在所有应用程序中都能正常运行。因此,如果我在应用程序中发现一个行为不一样的列表,我会感到惊讶。你可以随时把手指放回屏幕上,停止这种放纵


这就是说,如果您想做额外的工作,您可以对列表视图进行子类化,并覆盖其on-touch方法。知道该做什么的最好方法是获取ListView()的源代码。

我的意见是,您不应该修改此行为,因为用户期望的是fling行为

不过,我要回答你的问题。我还没试过这个,但理论上它应该能起作用


列表视图实施一个检查,并使用该方法检查当前状态是否为。在您确定滚动通过一次轻击完成后,您可以使用该方法获得您的
列表视图的第一个可见位置,并且从那里可以使用放置在
getFirstVisiblePosition()中的位置
值作为参数。

我没有尝试的解决方案,但由于对于API级别低于8的API不可用,因此这对我不起作用

我同意,改变默认行为不是一个好主意,但有时你需要这样做。这里是我的(肮脏的)解决方案,它使用反射。这不是推荐的方法,因为这是一个黑客,但它对我来说是有效的。也许有更好的解决办法,但我没有找到

class StopListFling {

    private static Field mFlingEndField = null;
    private static Method mFlingEndMethod = null;

    static {
        try {
            mFlingEndField = AbsListView.class.getDeclaredField("mFlingRunnable");
            mFlingEndField.setAccessible(true);
            mFlingEndMethod = mFlingEndField.getType().getDeclaredMethod("endFling");
            mFlingEndMethod.setAccessible(true);
        } catch (Exception e) {
            mFlingEndMethod = null;
        }
    }

    public static void stop(ListView list) {
        if (mFlingEndMethod != null) {
            try {
                mFlingEndMethod.invoke(mFlingEndField.get(list));
            } catch (Exception e) {
            }
        }
    }
}

我们查找android源代码(AbsListView),给它一个ACTION\u CANCEL touchEvent,就可以停止这次放纵。这很容易

listView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));

通过重写onTouchEvent并调用smoothScrollBy,可以防止抛出API 8中的ListView

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
        case MotionEvent.ACTION_UP:
        this.smoothScrollBy(0, 0);
        break;
    }
    return super.onTouchEvent(ev);
}

这取代了fling滚动,改为滚动0px。

我将回应MarvinLabs关于保持列表与用户期望的工作方式一致的评论。谢谢,这对我非常有用。本机Android小部件也会这样做(这只是猜测而已):如果将listview放在viewpager中并抛出列表,然后向左滑动,页面将手动停止滚动。@这是完整代码,只需在列表视图实例上使用此方法停止滚动即可。没什么好解释的。它使用反射来破解ListView的内部字段。无论如何,如果您的目标是API>=8,我建议您首先查看smoothScrollToPosition。这是正确的答案。这一点应该被接受,因为它可以不经思考地工作。好工作伙伴!