当我为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();
}
}
答案 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)
这是正常的,因为setOnScrollListener
(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();
}
}
});
答案 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);
}
});