【问题标题】:Android - ListView duplicate eventsAndroid - ListView 重复事件
【发布时间】:2009-10-13 18:54:33
【问题描述】:

在我的应用程序中,我有一个由 ArrayAdapter 支持的 ListView。在其中,我正在检测 OnScrollListener#onScroll 方法中的事件以查找列表的结尾。我注意到在手机(MyTouch)上,轨迹球和手势/触摸滚动都会触发两次事件。在模拟器上,我通过滚轮和点击和药物滚动获得相同的行为。但是在模拟器中,如果我使用向下箭头按钮滚动该事件只会触发一次。

代码如下:

this.view.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScroll(final AbsListView view, final int first, 
                                final int visible, final int total) {
        // detect if last item is visible
        if (visible < total && (first + visible == total)) {
            Log.d("OnScrollListener - end of list", "fvi: " + 
               first + ", vic: " + visible + ", tic: " + total);
            // this line gets called twice
            onLastListItemDisplayed(total, visible);
        }
    }
}

如何抑制或处理这种行为?我只需要一个事件,并尽量不恢复到布尔字段等愚蠢的黑客攻击。

据我所知 - 两个事件都有相同的堆栈跟踪

Thread [<3> main] (Suspended (breakpoint at line 116 in SearchResultsView$4)) 
 SearchResultsView$4.onScroll(AbsListView, int, int, int) line: 116 
 ListView(AbsListView).invokeOnItemScrollListener() line: 655 
 ListView.arrowScrollImpl(int) line: 2256 
 ListView.arrowScroll(int) line: 2172 
 ListView.commonKey(int, int, KeyEvent) line: 1977 
 ListView.onKeyMultiple(int, int, KeyEvent) line: 1929 
 KeyEvent.dispatch(KeyEvent$Callback) line: 899 
 ListView(View).dispatchKeyEvent(KeyEvent) line: 3647 
 ListView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 744 
 ListView.dispatchKeyEvent(KeyEvent) line: 1909 
 FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 
 LinearLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 
 PhoneWindow$DecorView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 746 
 PhoneWindow$DecorView.superDispatchKeyEvent(KeyEvent) line: 1708 
 PhoneWindow.superDispatchKeyEvent(KeyEvent) line: 1197 
 SearchResultsView(Activity).dispatchKeyEvent(KeyEvent) line: 1967 
 PhoneWindow$DecorView.dispatchKeyEvent(KeyEvent) line: 1684 
 ViewRoot.deliverKeyEventToViewHierarchy(KeyEvent, boolean) line: 2329 
 ViewRoot.handleFinishedEvent(int, boolean) line: 2299 
 ViewRoot.handleMessage(Message) line: 1621 
 ViewRoot(Handler).dispatchMessage(Message) line: 99 
 Looper.loop() line: 123 
 ActivityThread.main(String[]) line: 4203 
 Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] 
 Method.invoke(Object, Object...) line: 521 
 ZygoteInit$MethodAndArgsCaller.run() line: 791 
 ZygoteInit.main(String[]) line: 549 
 NativeStart.main(String[]) line: not available [native method]

附: Bug is created

附言并以非常有用的回复结束The trackball and the touch screen send several motion events very rapidly. This behavior is expected.

【问题讨论】:

  • 我记得也遇到过一次。一直没有找到解决办法。祝你好运。
  • 我在 Android 错误跟踪网站上发布了一个错误,看看他们是否至少可以对此发表评论

标签: android listview onscroll


【解决方案1】:

既然谷歌的好人说这是as intended,那么处理这个问题的一种丑陋残酷的方式对我有用。基本上这里的假设是,随着事件的发布,我将最后保存的第一项索引与onScroll 调用中传递的索引进行比较。如果这些不匹配,我只会处理事件:

    this.view.setOnScrollListener(new OnScrollListener() {
        private int lastSavedFirst = -1;
        @Override
        public void onScroll(final AbsListView view, final int first, final int visible, final int total) {
            // detect if last item is visible
            if (visible < total && (first + visible == total)) {
                // only process first event
                if (first != lastSavedFirst) {
                    lastSavedFirst = first;
                    Log.d("OnScrollListener - end of list", "fvi: " + first + ", vic: " + visible + ", tic: "
                            + total);
                    onLastListItemDisplayed(total, visible);
                }
            }
        }

        @Override
        public void onScrollStateChanged(final AbsListView view, final int scrollState) {
            // Log.d("OnScrollListener", "state: " + scrollState);
        }
    });

【讨论】:

    【解决方案2】:

    我在滚动 ListView 时也遇到了多个事件触发的问题。当我通过阈值时,我打算加载更多 ListItems。但是,这总是会导致多个调用的 AsyncTasks 填充我的 ListView 的速度比预期的要快。

    我在this blogpost 中找到了一个很好的解决方案。尽管您不喜欢此解决方案,但它基本上包括对布尔值的检查。我发现它也有些 hacky,但我没有想出另一种解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 2018-02-26
      • 2013-12-01
      • 1970-01-01
      相关资源
      最近更新 更多