4

私のアプリには、ArrayAdapter に基づく ListView があります。その中で、リストの最後を見つけるために OnScrollListener#onScroll メソッドでイベントを検出しています。電話 (MyTouch) では、トラック ボールとジェスチャ/タッチ スクロールの両方でイベントが 2 回トリガーされることに気付きました。エミュレーターでは、スクロール ホイールとクリック アンド ドラッグ スクロールで同じ動作が得られます。ただし、エミュレーターで下矢印ボタンを使用してスクロールすると、イベントは1回だけ発生します。

コードは次のとおりです。

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]

PSバグが作成されました

PPS そして、非常に有用な返信で締めくくられましたThe trackball and the touch screen send several motion events very rapidly. This behavior is expected.

4

2 に答える 2

4

グーグルの善良な人々は、これが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);
        }
    });
于 2009-10-13T20:55:28.070 に答える
0

ListViewをスクロールしているときに複数のイベントが発生するというこの問題もあります。しきい値を渡した瞬間に、より多くの ListItems をロードするつもりでした。ただし、これにより常に複数の AsyncTasks が呼び出され、ListView が必要以上に高速に読み込まれました。

このブログ投稿で良い解決策を見つけました。このソリューションは嫌いですが、基本的にブール値のチェックが含まれています。私はそれもある種のハッキーだと思いますが、別の解決策は思いつきませんでした。

于 2012-02-20T21:24:15.163 に答える