概述
检测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开始停止滑动的方案检测ScrollView开始停止滑动的方案旧方案新方案的全部内容,希望文章能够帮你解决检测ScrollView开始停止滑动的方案检测ScrollView开始停止滑动的方案旧方案新方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复