文章目录
背景实现手势监听器的声明和创建对重写的相关方法 onScroll() 说明手势监听器接管View的触屏事件验证结果背景
项目中要实现控件的滑动监听其实还是挺常见的,这里就简单的做一下记录。
实现的方式也有好几种,我这里就只实现一种:自己觉得对手势滑动的判断比较准确且稳定的一个方式。
实现
手势监听器的声明和创建
声明如下:private GestureDetector detector = null;// 声明一个手势监听器
创建如下:
// 创建 GestureDetector 对象,并重写相关方法detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic 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;// 事件被消费了,不会继续传递}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {// 需要用户手指触摸屏幕后的一次稍微快速的滑动并且手指抬起后才会回调该方法// 如果速度较慢,那么该方法不会回调(可能也正好解释了 fling:猛动 这个词的意思吧)Log.e("TAG", "onFling");return true;// 事件被消费了,不会继续传递}});
上面创建的代码中,我在重写的方法添加了一些关键注释,建议同学们都了解一下,对加深自己的理解有作用。
对重写的相关方法 onScroll() 说明
首先看下该方法的源码:
/*** 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 有触屏事件,所以肯定要给 View 设置触摸事件,如下:
// 显示设置一下控件可点击linear.setClickable(true);// 线性布局设置触摸监听事件linear.setOnTouchListener(new View.OnTouchListener() {@SuppressLint("ClickableViewAccessibility")@Overridepublic 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
感兴趣的同学可以去下载安装体验一下。
技术永不眠,我们下期见!