当我设置listView.onScrollListener(this)时,onScroll被调用,但没有任何联系

当我为我的ListView设置onScrollListener ,它调用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(); } } 

Related of "当我设置listView.onScrollListener(this)时,onScroll被调用,但没有任何联系"

这很正常,因为AbsListViewListView的超类)中的AbsListView的源代码执行此操作:

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

只是提醒,根据javadoc

MotionEvent.ACTION_SCROLL

这个动作总是被传递到指针下的窗口或者视图中,这个指针可能不是当前被触摸的窗口或视图。

此操作不是触摸事件,因此将其传递到onGenericMotionEvent(MotionEvent)而不是onTouchEvent(MotionEvent)。

因此, motionEvent.getAction()永远不会得到SCROLL事件。 检查移动将做这项工作

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

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

我使用这个解决scheme,它适用于我:

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

只有当visibleItemCount> 0时才可以执行需要的任务;

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

为我工作的解决scheme! 上面的答案组合我做出了解决scheme! 感谢@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); } });