【问题标题】:Stop ListView scroll animation停止 ListView 滚动动画
【发布时间】:2011-09-16 04:53:32
【问题描述】:

我有一个ListView,大约有 100 个条目。当用户从下到上“滑动”时,它开始滚动并继续滚动,即使手指不再触摸显示屏。

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

【问题讨论】:

    标签: android listview scroll android-listview


    【解决方案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

        【讨论】:

          猜你喜欢
          • 2014-07-14
          • 1970-01-01
          • 2021-01-17
          • 1970-01-01
          • 2015-01-15
          • 2016-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多