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

时间:2013-04-18 02:08:00

标签: android android-listview onscroll

当我为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();
    }
}

5 个答案:

答案 0 :(得分:58)

根据

的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;
        }   
}

答案 1 :(得分:23)

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

 public void setOnScrollListener(OnScrollListener l) {
        mOnScrollListener = l;
        invokeOnItemScrollListener();
    }

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.
    }

取决于你想要做什么,有很多方法可以避免这个问题。

编辑:

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

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

然后..

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

});

答案 2 :(得分:3)

我使用此解决方案,它对我来说很好:

public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                canScroll = false;
            } else if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING ||
                    scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                canScroll = true;

            }
        }

答案 3 :(得分:0)

只有当visibleItemCount>时,您才能执行必要的任务。 0;

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount){
    if (visibleItemCount > 0 ){
        //perform the task to be done
    }
}

答案 4 :(得分:0)

为我工作的解决方案!结合以上的答案,我做出了解决方案! 感谢@LuxuryMode和@CrazyGreenHand

我的TouchListener: 由于没有触发MotionEvent.ACTION_SCROLL,我使用了MOVE动作

 expandableListView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(view == expandableListView && motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
                userScrolled = true;
            }
            return false;
        }
    });

我的滚动侦听器:

  expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {

        }

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem == 0){
                swipeRefreshLayout.setEnabled(true);
            }else {
                swipeRefreshLayout.setEnabled(false);
            }
            int lastVisibleItem = absListView.getLastVisiblePosition();
            if (userScrolled&&!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                onLoadMore();
                isLoading = true;
            }
            Log.d(TAG, "onScroll: firstVisibleItem=>"+firstVisibleItem+"==>visibleItemCount=>"+visibleItemCount+"==>totalItemCount==>"+totalItemCount+"==>lastVisibleItem==>"+lastVisibleItem);
        }
    });