停止 ListView 滚动动画
Posted
技术标签:
【中文标题】停止 ListView 滚动动画【英文标题】:Stop ListView scroll animation 【发布时间】:2011-09-16 04:53:32 【问题描述】:我有一个ListView
,大约有 100 个条目。当用户从下到上“滑动”时,它开始滚动并继续滚动,即使手指不再触摸显示屏。
此时有没有办法停止滚动动画?
【问题讨论】:
【参考方案1】:我们查找android源代码(AbsListView),给它一个ACTION_CANCEL touchEvent,可以停止fling。这很容易。
listView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));
【讨论】:
这是正确的答案。这应该被接受,因为它无需反思即可工作。不错的工作伙伴!【参考方案2】:我没有尝试Pompe de velo
的解决方案,但由于smoothScrollToPosition()
不适用于低于 8 的 API 级别,这对我不起作用。
我同意,更改默认行为不是一个好主意,但有时您需要这样做。所以这是我使用反射的(脏)解决方案。到目前为止,这不是推荐的方式,因为它是一种 hack,但它对我有用。可能有更好的解决方案,但我没有找到。
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 小部件也会这样做(这只是一个猜测..):如果您将 listview 放在 viewpager 中并翻转列表,然后向左滑动,pager 将手动停止滚动。 @arul 这是完整的代码,只需在列表视图实例上使用此方法即可停止滚动。没什么好解释的。它使用反射来破解 ListView 的内部字段。无论如何,如果您的目标 API >= 8,我建议您先看看 smoothScrollToPosition。【参考方案3】:当然有办法做到这一点。但在我看来,更重要的是是否建议这样做。
该列表是一个标准的 Android 控件,在所有应用程序中都具有一致的行为。因此,如果我发现一个列表在您的应用程序中表现不同,我会感到惊讶。您可以随时将手指放回屏幕以停止投掷。
也就是说,如果您想做额外的工作,您可以子类化列表视图并覆盖其 on touch 方法。最好的方法是获取 ListView 的源代码 (ListView in Android 1.6)。
【讨论】:
我会回应 MarvinLabs 的评论,即让您的列表与用户期望它的工作方式保持一致。【参考方案4】:您可以通过重写 onTouchEvent 并调用 smoothScrollBy 来防止 API 8 中的 ListViews 被丢弃。
@Override
public boolean onTouchEvent(MotionEvent ev)
switch (ev.getAction())
case MotionEvent.ACTION_UP:
this.smoothScrollBy(0, 0);
break;
return super.onTouchEvent(ev);
这会取代快速滚动并滚动 0px。
【讨论】:
【参考方案5】:我的意见是你不应该修改这种行为,因为投掷行为是用户所期望的。
但是,对于您的问题。我还没有尝试过,但理论上它应该可以工作。
为您的ListView
实现OnScrollListener
并使用onScrollStateChanged()
方法检查当前状态是否为SCROLL_STATE_FLING
。在您确定滚动执行后,您可以使用getFirstVisiblePosition()
方法获得ListView
的第一个可见位置,然后您可以使用smoothScrollToPosition()
在其中输入getFirstVisiblePosition()
值作为一个论点。
【讨论】:
【参考方案6】:如果您从列表视图中禁用默认动画,只需在 xml 中为根(主)布局设置 id 并在类中为根布局调用 void onClickListener
【讨论】:
以上是关于停止 ListView 滚动动画的主要内容,如果未能解决你的问题,请参考以下文章
ListView 项目滚动动画(类似“UIKit Dynamics”)
在 Flutter 中向下滚动 ListView.builder 时出现不需要的动画
当您一直滚动到 ListView.builder 的顶部时,如何禁用动画