GestureDetector监听
GestureDetector即识别手势,如点击、长按、滑动等手势操作。查看源码里面的方法很多,主要使用的也就那么几个。
- onDown(MotionEvent e):按下屏幕的的回调。
- onLongPress(MotionEvent e):长按的回调(长按的时间不同设备可能不同)
- onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY): 滑动时的回调
- onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY): 滑动后执行后的回调
实现监听也很简单,只要继承GestureDetector.SimpleOnGestureListener重写方法即可,当然,直接new 一个SimpleOnGestureListener也可以。
class myGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (e1.getX() - e2.getX() > 200) {
//左滑
} else if (e2.getX() - e1.getX() > 200) {
右滑
}
if (e1.getY() - e2.getY() > 200) {
//上滑
}
if (e2.getY() - e1.getY() > 200) {
//下滑
}
return super.onFling(e1, e2, velocityX, velocityY);
}
}
GestureDetector gestureDetector = new GestureDetector(new myGestureListener());
//实现某个控件的监听只需将控件的事件传递给gestureDetector即可
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return false;
}
});
NestedScrollView
大家都知道NestedScrollView是一个滑动控件,自身就有滑动事件,同事这个控件也有滑动时的一个回调
- onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) : 滑动时回调
注意:这里的scrollX,scrollY是指滑动后的位置,oldScrollX,oldScrollY指滑动前的位置,位置是已屏幕左上角为原点的,相当于一个坐标轴。
例如我们想NestedScrollView自动滑到某个位置就可以调用NestedScrollView的scrollTo(x,y)这个方法,实现监听也很简单。
scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
}
});
}
注意:这里的x和y是指每次滑动的值,而不是滑动的总值,想要知道滑动的总值,自己定义变量计算即可,如下:
int y = 0;
scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
try {
y += scrollY - oldScrollY;
//这样就可以计算出垂直方向滑动的总距离了
}catch (Exception e){
e.printStackTrace();
}
}
});
RecyclerView
RecyclerView是我们常用的一个列表控件,因此他自身滑动就可以监听,强烈建议不要嵌套NestedScrollView和RecyclerView,这样会导致滑动很不流畅,看到网上有很多博客说是解决这种嵌套卡顿的方法,我也尝试了下,在某种程度上的确滑动变得流畅了,但是消耗的性能很大,最好采用addView和的方式。
- onScrolled(RecyclerView recyclerView, int dx, int dy):滑动时回调 说明:这里的dx和dy两个参数是指每次滑动的距离,如需计算总距离只要定义变量+=dy或者+=dx即可。
RecyclerView的监听只要添加RecyclerView.OnScrollListener即可,代码如下:
rv_advertising.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
MotionEvent
触摸动作触发的输入事件由MotionEvent回调的,每个触摸时间类型都由MotionEvent的常量表示:
- ACTION_DOWN:在第一个手指按下时
- ACTION_POINTER_DOWN:后续手指按下时触发
- ACTION_MOVE:任何一个手指的移动触发
- ACTION_POINTER_UP:非最后一个手指抬起触发
- ACTION_UP:最后离开屏幕时触发
- ACTION_CANCEL:触摸事件序列被中断时触发,一般是对应View的parent阻止的,比如触摸超出区域时。