检测ScrollView开始停止滑动的方案
2017-08-17 15:05
676 查看
检测ScrollView开始停止滑动的方案
旧方案
如何检测scrollview的滑动开始和滑动停止,滑动开始可以用onScrollChange来判断,那么停止呢。
一开始的时候我是判断200ms内,scrollY是否改变,如果未改变就判断为停止了,核心代码如下。工程名为DetectScrollStop。但是这样不优雅,有没有更好的方法呢?
detector = new ScrollViewStopDetector(scrollView); scrollView.addOnScrollChangeListener(new FixedNestedScrollView.OnScrollChangeListener() { @Override public void onScrollChange(FixedNestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { detector.start(); } }); detector.setListener(new ScrollViewStopDetector.OnScrollStateListener() { @Override public void onStop() { anim.animShow(); } @Override public void onStart() { anim.animHide(); } });
public class ScrollViewStopDetector { private static final int SCROLLING = 0; private static final int IDLE = 1; private int state=IDLE; public interface OnScrollStateListener { void onStop(); void onStart(); } public ScrollViewStopDetector(FixedNestedScrollView scrollView) { this.scrollView = scrollView; } public OnScrollStateListener getListener() { return listener; } public void setListener(OnScrollStateListener listener) { this.listener = listener; } private OnScrollStateListener listener; private Handler handler = new Handler(); private FixedNestedScrollView scrollView; private int lastScrollY; public void start() { LogUtil.fish("start"); setState(SCROLLING); handler.removeCallbacksAndMessages(null); lastScrollY = scrollView.getScrollY(); handler.postDelayed(runnable, 200); } private Runnable runnable = new Runnable() { @Override public void run() { int nowScrollY = scrollView.getScrollY(); if (!scrollView.isBeingDragged()&&nowScrollY == lastScrollY) { //表示停止了 LogUtil.fish("setState idle"); setState(IDLE); } else { //再等200ms LogUtil.fish("again"); handler.postDelayed(runnable, 200); } lastScrollY = nowScrollY; } }; private void setState(int newState) { if (newState != state) { state = newState; if (state == SCROLLING) { listener.onStart(); } else { listener.onStop(); } } } }
新方案
想了下,scrollview的滑动停止有以下3种情况1、滑动,然后停止
2、fling 然后减速停止
3、fling,触底停止
4、fling,然后点击,然后停止
那么我在scrollview里检测,然后给他设置好相应的scrollstate,就可以了。参考listview,我把state分成3类,SCROLL_STATE_IDLE、SCROLL_STATE_TOUCH_SCROLL、SCROLL_STATE_FLING。第一种情况和第四种情况都好办,在onTouchEvent的事件里处理就好了。
2和3比较麻烦,首先看2,因为不知道什么时候2停止下来,只能通过监测computesScroll来实现。一开始的时候,我是认为,在下面的case1,和case2里来检测就行了。但是drag的时候会进入到case2,不行,所以我们只关注case 1,没错case1 可以检测到情况2(
在
if (oldX != x || oldY != y)不成立的时候,就认为fling停止了。),但是无法检测到情况3,如何检测情况3呢?对于3呢,触底的时候会调用springBack,所以我直接粗暴的在springBack的时候认为fling停止了。工程名为DetectScrollStop2
@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { int oldX = getScrollX(); int oldY = getScrollY(); int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { final int range = getScrollRange(); final int overscrollMode = ViewCompat.getOverScrollMode(this); final boolean canOverscroll = overscrollMode == ViewCompat.OVER_SCROLL_ALWAYS || (overscrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0); overScrollByCompat(x - oldX, y - oldY, oldX, oldY, 0, range, 0, 0, false); if (canOverscroll) { ensureGlows(); if (y <= 0 && oldY > 0) { mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity()); } else if (y >= range && oldY < range) { mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity()); } } }else{ //case1 reportScrollStateChange(OnScrollStateChangeListener.SCROLL_STATE_IDLE); } }else{ //case 2 reportScrollStateChange(OnScrollStateChangeListener.SCROLL_STATE_IDLE); } }
相关文章推荐
- 如何检测ScrollView和TableView是处在开始拖动,上移,下移,减速或者停止等状态
- android监听ScrollView滑动停止
- ScrollView监听停止滑动,判断是否滑到底部
- Android中监听ScrollView滑动停止和滑动到底部
- 加载优化之缓存Lru,滑动停止的时候开始加载,滑动的时候不加载
- Android中Scrollview、ViewPager、ListView,使ScrollView滑动到开始的位置。
- Android中监听ScrollView滑动停止和滑动到底部
- Android 自定义ScrollView嵌套滚动兼容,监听滑动状态:顶部、底部、停止、滑动中
- Android Gallery 滑动停止监听方案
- scrollview 添加拖拽后失去按钮滑动功能的修复方案
- Android中监听ScrollView滑动停止和滑动到底部
- 解决ListView与ScrollView的滑动冲突(非自定义View方案)
- iOS自定义scrollview的滑动停止位置
- ScrollView快速滑动或拖拽停止事件监听
- Android - ScrollView 监听滑动停止,顶部还是底部?
- scrollview滑动到某个坐标的时候就停止滑动解决办法
- Android ScrollView嵌套ViewPager滑动失效和无法正常滑动冲突问题解决方案
- iOS开发问题----UIPickerView判断时候正在滑动的问题(检测“滚轮”启动和停止)
- 完美解决隐藏Listview和RecyclerView去掉滚动条和滑动到边界阴影的方案