博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈Android 事件分发机制(二)
阅读量:7025 次
发布时间:2019-06-28

本文共 2454 字,大约阅读时间需要 8 分钟。

在上一篇文章中,浅谈Android 事件分发机制(一),简要分析了一下事件分发机制的原理,总结一下就是事件层层传递,直到被消费,原理看似简单,但是在实际使用过程中,场景各不相同,复杂程度也就因产品而异,这篇文章就通过给view加移动来模拟事件分发。

触摸事件

这里涉及到几个与手指触摸相关的常见事件:

坐标系对于单指触控移动来说,一次简单的交互流程是这样的: 手指落下(ACTION_DOWN) -> 移动(ACTION_MOVE) -> 离开(ACTION_UP)

坐标系

Android坐标系以手机屏幕左上角的顶点为坐标原点,从该点向右为x轴正方向,从该点向下为y轴正方向。 上图所示,一次触摸涉及到多种距离的计算, 上图所标注的方法可以分为两类,一类是View提供的方法,一类是MotionEvent提供的方法。

View提供的:

getTop():获取到view自身的顶边到其父布局顶边的距离

getLeft():获取到view自身的左边到其父布局左边的距离

getRight():获取到view自身的右边到其父布局左边的距离

getBottom():获取到view自身底边到其父布局顶边的距离

MotionEvent提供的方法:

getX():获取触摸点距离控件左边的距离,即视图坐标

getY(): 获取触摸点距离控件顶边的距离,即视图坐标

getRawX():获取触摸点距离整个屏幕左边的距离,即绝对坐标

getRawY():获取触摸点距离整个屏幕顶边的距离,即绝对坐标

知道了以上的知识点后,基于做view的移动,这里还是三个视图ViewC、ViewGroupB、ViewGroupA

C添加移动

给ViewC(蓝色区域)添加移动 onTouchEvent返回true,自身消费事件。 手指按下MotionEvent.ACTION_DOWN,记录当前距离控件左边和顶边的距离lastXlastY。 手指移动时MotionEvent.ACTION_MOVE,获取当前距离控件左边和顶边的距离xy,减去手指按下时记录的距离lastXlastY,计算得到移动的距离,移动的距离加上view距离父布局的距离,得到相对于父布局的四个点坐标,layout重新确认位置。 手指离开MotionEvent.ACTION_UP,设置view距离父布局的margin,这边的操作主要是固定view的位置,后续和视图B一起移动时可固定位置。

private int lastX;private int lastY;@Overridepublic boolean onTouchEvent(MotionEvent event) {    int x = (int) event.getX();    int y = (int) event.getY();    switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            lastX = x;            lastY = y;            break;        case MotionEvent.ACTION_MOVE:            //计算移动的距离            int offsetX = x - lastX;            int offsetY = y - lastY;            int l = getLeft() + offsetX;            int b = getBottom() + offsetY;            int r = getRight() + offsetX;            int t = getTop() + offsetY;            //重新确认位置            layout(l, t, r, b);            break;        case MotionEvent.ACTION_UP:            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();            params.setMargins(getLeft(), getTop(), 0, 0);            break;        default:            break;    }    return true;}复制代码

B添加移动

同样给ViewGroupB添加以上的代码用于B的移动。(蓝色的视图C,黄色的视图B)

情况一:如上图 这里视图B、C的onTouchEvent都返回true,在C区域滑动,viewC消费了事件,不再传递给B;只有在B、C不重叠的区域滑动,C才会移动,这时没有接触到C,所以不会触发C的事件。因为我们在C的MotionEvent.ACTION_UP手指离开时固定了C到父布局(B)的距离,所以C相对B的位置没变。

情况二:如上图,将C的onTouchEvent返回false,在C区域滑动,事件没有消费,传递给到了B,B可以滑动,在不重叠区域一样可以滑动B。 如果B把事件拦截了onInterceptTouchEvent返回true,那么效果和情况二相同的,不管C的onTouchEvent返回啥,都响应不了。 这里模拟了视图B、C的滑动,A的话原理相同,这里就不再描述。 浅谈android事件分发的两篇文章结束了,这里只是简单描述模拟了事件分发。日常项目中若是遇到情况怕是更为复杂,想要彻底玩转事件分发机制还需要进一步的研究。

转载于:https://juejin.im/post/5c3c9c6a6fb9a049b7809d8f

你可能感兴趣的文章
约束用起来
查看>>
Javascript加速运动与减速运动
查看>>
HTTP学习
查看>>
scala学习手记29 - 偏应用函数
查看>>
冲刺第一周第五天
查看>>
Java 接口
查看>>
Android 微信第三方登录
查看>>
深入P2P——BT种子解析
查看>>
centos 建立Clamav自动扫描脚本
查看>>
硬盘的读写原理
查看>>
实例 centos自动挂载、备份windows共享文件夹,并删除第7日前当天的备份
查看>>
LNMP下动静分离部署phpmyadmin软件包
查看>>
如何写更好的自动化测试用例
查看>>
60再谈指针
查看>>
repost
查看>>
android异步加载AsyncTask
查看>>
GCC Stack-Smashing Protector
查看>>
虚拟机Visualbox安装Ubuntu Server
查看>>
用带余除法可以解决一切部分分式的题目
查看>>
vs 生成事件
查看>>