因为项目里用到了ScrollView, 并需要实现类似于ListView的滑动监听回调,所以自定义了一套实现方式支持这些事件, 基本满足了业务需求;
public interface OnMyScrollListener {
int SCROLL_STATE_FLING = 2; //手指滑动后松开,自动滑动
int SCROLL_STATE_IDLE = 0; //不滑动
int SCROLL_STATE_TOUCH_SCROLL = 1; //手指按着屏幕滑动
void onScrollStateChanged(MyScrollView view, int state);
void onScroll(MyScrollView view, int y); //滑动距离
void onScrollToTop(); //滑到顶部
void onScrollToBottom(); //滑到底部
}
原理:
1、判断fling? ScrollView的fling都会执行ScrollView.fling函数, 所以覆盖该函数并在函数体执行回调, 表示已开始fling;
2、判断drag? ScrollView有个成员变量mIsBeingDragged, 覆盖onTouch函数判断MOVE事件时反射读取该参数;
/**
* True if the user is currently dragging this ScrollView around. This is
* not the same as 'is being flinged', which can be checked by
* mScroller.isFinished() (flinging begins when the user lifts his finger).
*/
private boolean mIsBeingDragged = false;
3、判断idle? 网络上有2个方法: 1、使用延迟消息,判断scroll位置是否发生变化(比较靠谱); 2、反射读取OverScroller的isFinished函数(不靠谱)。 我是用onDraw函数实现的, 滑动结束时会执行多次onDraw函数;
4、判断滑到顶部? 判断scrollY等于0, 即滑动距离为0;
5、判断滑到底部? ScrollView本身高度+上下间距+滑动距离 等于 子View 高度;
日志:
07-08 07:24:49.540 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:IDLE
07-08 07:24:49.847 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动底部
07-08 07:24:51.894 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:DRAG
07-08 07:24:51.931 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:FLING
07-08 07:24:52.975 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:IDLE
滑到顶部
07-08 07:24:54.757 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:DRAG
07-08 07:24:54.812 8388-8388/com.byrcegao.myscrollviewtest D/brycegao: 滑动状态:FLING
07-08 07:24:55.219 8388-8388/