当我为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();
}
}
提醒一下,根据
的javadocMotionEvent。ACTION_SCROLL :
这个动作总是传递给指针下的窗口或视图,它可能不是当前触摸的窗口或视图。
这个动作不是一个触摸事件,所以它被传递给onGenericMotionEvent(MotionEvent)而不是onTouchEvent(MotionEvent)。
因此,motionEvent.getAction()
将永远不会得到SCROLL事件。检查MOVE是否会完成任务
您也可以在OnScrollListener
onScrollStateChanged
方法中做类似的事情@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
userScrolled = true;
}
}
这是正常的,因为AbsListView
(ListView
的超类)中setOnScrollListener
的源代码是这样做的:
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();
}
}
});
我使用这个解决方案,它对我来说很好:
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
}
}
为我工作的解决方案!结合以上答案,我做出了解决方案!!感谢@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);
}
});