35

当我onScrollListener为 my设置时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();
    }
}
4

5 回答 5

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;
        }   
}
于 2013-08-22T15:57:52.070 回答
23

这很正常,因为setOnScrollListenerin AbsListView(的超类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();
        }
    }

});
于 2013-04-18T02:41:32.227 回答
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;

            }
        }
于 2016-05-14T05:46:09.583 回答
0

只有当 visibleItemCount > 0 时,您才能完成需要的任务;

public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount){
    if (visibleItemCount > 0 ){
        //perform the task to be done
    }
}
于 2015-01-14T07:23:49.373 回答
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);
        }
    });
于 2016-12-01T06:11:57.893 回答