分析源码,初步断定原因:
当ListView滚动到最底部(最顶部)时,触发了2.3新引入的视觉特效。这部分逻辑里看到了特效相关的代码,但却没找到通知reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE)的相关代码。其它地方通知reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE)的地方伴随着mTouchMode = TOUCH_MODE_REST,而特效代码这里却只有mTouchMode = TOUCH_MODE_REST,无reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE),源码如下:
void startSpringback() {
Log.d(tag, "simba startSpringback");
if (mScroller.springBack(0, mScrollY, 0, 0, 0, 0)) {
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
post(this);
} else {
mTouchMode = TOUCH_MODE_REST;
//这里没有调用下面注释的代码,导致ListView注册的OnScrollListener不会得到通知
//reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
}
在网上找到相关的解决方法如下:
为ListView设置一个OnTouchListener,在这个OnTouchListener中当MotionEvent的action等于 MotionEvent.ACTION_UP或者MotionEvent.ACTION_CANCEL时强制调用一次
onScrollStateChanged((AbsListView) view,OnScrollListener.SCROLL_STATE_FLING),
然后再调用一次
onScrollStateChanged((AbsListView) view,OnScrollListener.SCROLL_STATE_IDLE)
代码如下:
public class FingerTracker implements View.OnTouchListener {
private OnScrollListener myOnScrollListener;
public FingerTracker(OnScrollListener onScrollListener) {
myOnScrollListener = onScrollListener;
}
@Override
public boolean onTouch(View view, MotionEvent event) {
final int action = event.getAction();
boolean mFingerUp = action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_CANCEL;
if (mFingerUp) {
myOnScrollListener.onScrollStateChanged((AbsListView) view,
OnScrollListener.SCROLL_STATE_FLING);
myOnScrollListener.onScrollStateChanged((AbsListView) view,
OnScrollListener.SCROLL_STATE_IDLE);
}
return false;
}
}
为ListView设置自定义的OnTouchListener:
mListView.setOnTouchListener(new FingerTracker(this));
效果待测!
原文位置: