我有一个包含大约100个条目的ListView
。当用户从底部向上进行“fling”操作时,它开始滚动,并且即使手指不再触摸显示屏,它仍然会继续滚动。
有没有办法在这一点上停止滚动动画?
我有一个包含大约100个条目的ListView
。当用户从底部向上进行“fling”操作时,它开始滚动,并且即使手指不再触摸显示屏,它仍然会继续滚动。
有没有办法在这一点上停止滚动动画?
我们查找了Android源代码(AbsListView),给它一个ACTION_CANCEL的touchEvent,就可以停止fling。这很容易。
listView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0));
Pompe de velo
的解决方案,但由于低于API 8的版本中没有smoothScrollToPosition()
,所以这对我没有用。
我同意,改变默认行为不是一个好主意,但有时你需要这样做。因此,这是我的(肮脏)解决方案,它使用了反射。这绝不是推荐的方式,因为它是一种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) {
}
}
}
}
您可以通过重写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 scrolling)并代替为滚动0px。
当然有方法可以做到。但在我看来,更重要的是是否建议这样做。
列表是一个标准的Android控件,在所有应用程序中都表现出一致性。因此,如果我发现一个列表在您的应用程序中没有表现出相同的行为,我会感到惊讶。您可以随时将手指放回屏幕上来停止滑动。
话虽如此,如果您想要额外的工作,您可以子类化列表视图并覆盖其on touch方法。了解该怎么做的最好方法是获取ListView的源代码(Android 1.6中的ListView)。
我认为你不应该修改这个行为,因为用户期望的就是fling(迅速滑动)的效果。
但是,回答你的问题。虽然我没有尝试过,但从理论上讲它应该可以工作。
在你的ListView
上实现一个OnScrollListener
,并使用onScrollStateChanged()
方法检查当前状态是否为SCROLL_STATE_FLING
。确定滚动是由快速滑动执行后,您可以通过使用getFirstVisiblePosition()
方法获取ListView
的第一个可见位置,然后您可以使用smoothScorllToPosition()
,将您的getFirstVisiblePosition()
值作为参数放进去。