ListView滚动事件响应
ListView本身有一个OnScrollListener的接口,通过此接口可以监听列表的状态,滚动的个数,但是没法监听其精确的
滚动距离,上下滚动事件和滚动到表头或表尾事件,下面介绍如何对这些事件做响应。
1. 上下滚动事件的响应
1. 自定义一个继承至ListView的类。
2. 覆写onTouchEvent方法,监听触摸事件。
3. 定义一个有效滚动距离,当滑动的距离超过这个距离时才会触发滚动事件的响应。
private int mEffectiveDistance = 10;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent ev) {
mDetector.onTouchEvent(ev);
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
float currentY = ev.getY();
float distanceY = currentY - mPreviousY;
if (distanceY < -mEffectiveDistance) {
mPreviousY = currentY;
if (mCallbacks != null) {
mCallbacks.onScrollUp();
}
} else if (distanceY > mEffectiveDistance) {
mPreviousY = currentY;
if (mCallbacks != null) {
mCallbacks.onScrollDown();
}
}
break;
case MotionEvent.ACTION_DOWN:
mPreviousY = ev.getY();
break;
default:
break;
}
return super.onTouchEvent(ev);
}
2. 滚动到表头或表尾事件的响应
1. 自定义的ListView类要实现AbsListView.OnScrollListener接口。
2. 覆写onScrollStateChanged(AbsListView view, int scrollState)方法,监听列表的滚动事件,
其中view就是当前ListView,scrollState表示当前ListView的状态,它有三个状态:
SCROLL_STATE_IDLE(停止滚动的空闲状态)、
SCROLL_STATE_TOUCH_SCROLL(手指有接触屏幕并且带动ListView滚动的状态)、
SCROLL_STATE_FLING(手指离开的屏幕,ListView因为惯性还在滚动的状态)。
3. 当当前ListView状态是SCROLL_STATE_IDLE时进行事件监听。
滚动到表头的事件
- 当列表中的第一个子View的顶部Y坐标等于列表顶部Y坐标时响应
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
View firstChild = view.getChildAt(0);
if (view.getTop() == firstChild.getTop()) {
if (mCallbacks != null) {
mCallbacks.onScrollFirst();
}
}
}
}
滚动到表尾的事件
- 当列表中的最后一个子View的底部Y坐标等于列表底部Y坐标时响应
- 如果整个列表的长度比父View小,那么当最后一个子View的底部Y坐标等于列表的长度时响应
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int count = getCount();
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
&& getLastVisiblePosition() == count - 1) {
View lastChild = view.getChildAt(view.getChildCount() - 1);
int dist = view.getBottom() - lastChild.getBottom();
if (dist == 0) {
if (mCallbacks != null) {
mCallbacks.onScrollLast();
}
}
if (count < MIN_CHILD_COUNT) {
int childViewsHeight = (lastChild.getHeight()
+ getDividerHeight()) * count;
if (childViewsHeight < view.getHeight() && childViewsHeight == lastChild.getBottom()) {
if (mCallbacks != null) {
mCallbacks.onScrollLast();
}
}
}
}
}