当我设置listView.onScrollListener(this)时,会调用onScroll,但没有任何触摸

Sia*_*ash 33 android onscroll android-listview

当我onScrollListener为我设置时ListView,它会调用onScroll.这会导致崩溃,因为某些事情尚未初始化.

这是正常的吗?注意:即使没有触摸手机,也会发生这种情况.

public class MainActivity1 extends Activity implements OnClickListener, OnScrollListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout1);

    ListView lv = (ListView)findViewById(R.id.listview1);
    lv.setOnScrollListener(this);
    ...
}
...
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount){
    if( firstVisibleItem+visibleItemCount == totalItemCount ){
        pullContactList();
    }
}
Run Code Online (Sandbox Code Playgroud)

Cra*_*and 59

根据javadoc的说法,提醒一下

MotionEvent.ACTION_SCROLL :

此操作始终传递到指针下的窗口或视图,该指针可能不是当前触摸的窗口或视图.

此操作不是触摸事件,因此它将传递给onGenericMotionEvent(MotionEvent)而不是onTouchEvent(MotionEvent).

因此,motionEvent.getAction()永远不会得到SCROLL事件.检查MOVE是否可以完成工作

你也可以在onScrollStateChanged方法中做类似的事情OnScrollListener

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
        if(scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
            userScrolled = true;
        }   
}
Run Code Online (Sandbox Code Playgroud)


Lux*_*ode 23

这是正常的,因为setOnScrollListenerin AbsListView(超类ListView)的源代码执行此操作:

 public void setOnScrollListener(OnScrollListener l) {
        mOnScrollListener = l;
        invokeOnItemScrollListener();
    }
Run Code Online (Sandbox Code Playgroud)

invokeOnItemScrollListener做到这一点:

/**
     * Notify our scroll listener (if there is one) of a change in scroll state
*/
    void invokeOnItemScrollListener() {
        if (mFastScroller != null) {
            mFastScroller.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
        }
        if (mOnScrollListener != null) {
            mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
        }
        onScrollChanged(0, 0, 0, 0); // dummy values, View's implementation does not use these.
    }
Run Code Online (Sandbox Code Playgroud)

根据你想要做的事情,有很多方法可以避免这个问题.

编辑:

由于您只想在用户实际滚动时执行此操作,我想您可以执行以下操作:

    lv.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    if(view == lv && motionEvent.getAction() == MotionEvent.ACTION_SCROLL) {
                      userScrolled = true;
    }
return false;
                }
            });
Run Code Online (Sandbox Code Playgroud)

然后..

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount){
        if(userScrolled && firstVisibleItem+visibleItemCount == totalItemCount ){
            pullContactList();
        }
    }

});
Run Code Online (Sandbox Code Playgroud)

  • 为了完整性:您忘记了onTouch监听器中的return语句 (2认同)
  • 我无法相信文档中没有提到这种行为. (2认同)