项目中要实现控件的滑动监听其实还是挺常见的,这里就简单的做一下记录。
实现的方式也有好几种,我这里就只实现一种:自己觉得对手势滑动的判断比较准确且稳定的一个方式。
private GestureDetector detector = null;// 声明一个手势监听器
// 创建 GestureDetector 对象,并重写相关方法
detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("TAG", "onScroll");
Log.e("TAG", "onScroll distanceX = " + distanceX);
Log.e("TAG", "onScroll distanceY = " + distanceY);
//distanceY > 0 表示上滑了
if (distanceY > 0){
}
// distanceY > 0 表示下滑了
if (distanceY < 0){
}
// 表示左滑了
if(distanceX > 0){
Log.e("TAG", "表示左滑了");
}
// 表示右滑了
if(distanceX < 0){
Log.e("TAG", "表示右滑了");
}
return true;// 事件被消费了,不会继续传递
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// 需要用户手指触摸屏幕后的一次稍微快速的滑动并且手指抬起后才会回调该方法
// 如果速度较慢,那么该方法不会回调(可能也正好解释了 fling:猛动 这个词的意思吧)
Log.e("TAG", "onFling");
return true;// 事件被消费了,不会继续传递
}
});
上面创建的代码中,我在重写的方法添加了一些关键注释,建议同学们都了解一下,对加深自己的理解有作用。
首先看下该方法的源码:
/**
* Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
* current move {@link MotionEvent}. The distance in x and y is also supplied for
* convenience.
*
* @param e1 The first down motion event that started the scrolling.
* @param e2 The move motion event that triggered the current onScroll.
* @param distanceX The distance along the X axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1}
* and {@code e2}.
* @param distanceY The distance along the Y axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1}
* and {@code e2}.
* @return true if the event is consumed, else false
*/
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
源码讲了:当你触屏屏幕并开始滑动时就会触发这个方法,相关参数的解释也相对简单易懂
这里根据 distanceX
和 distanceY
的值大小来判断手势滑动的一个具体方向
distanceX
参数用来判断左右方向的一个滑动,当该值大于 0 表示手势左滑,当该值小于 0 表示手势右滑distanceY
参数用来判断上下方向的一个滑动,当该值大于 0 表示手势上滑,当该值小于 0 表示手势下滑不过我在 onScroll()
方法里面的判断只是比较粗略的(只用到了其中一个参数来做判断),如果同学们想很准确的表示左右滑动或者上下滑动,就需要用到两个参数(通过对参数进行值的约束来达到准确的判断)
这里因为一些布局或者是控件的顶层父类其实都是 View,所以我这里拿 View 来说明。
既然 View 有触屏事件,所以肯定要给 View 设置触摸事件,如下:
// 显示设置一下控件可点击
linear.setClickable(true);
// 线性布局设置触摸监听事件
linear.setOnTouchListener(new View.OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
// 手势监听器分析给定view(这里是linearLayout布局)的触屏事件
// 相当于由手势监听器来接管这个view的触屏事件
return detector.onTouchEvent(event);
}
});
在触摸事件监听的代码中返回 detector.onTouchEvent(event);
表示让手势监听器来消费这个触屏事件,就相当于由手势监听器接管了该事件。
注意:记得给 View
设置一下可点击属性为 true
,让手势监听器对象能成功的消费这个 View
的触屏事件
同学们只需要在判断的地方添加打印 log
日志代码,然后运行一下项目,自己手势滑动一下看看日志输出即可。
如下图示:
这里不直观,我给出一个 demo
中的 gif动图
演示,是手势上下滑动控制月亮
亮度动画
的渐变,如下:
demo apk
下载链接百度网盘
xv8c
感兴趣的同学可以去下载安装体验一下。
技术永不眠,我们下期见!