android 控件动画移动后 还占位,每日一问 | 为什么属性动画移动一个控件后,目标位置仍然能响应用户事件?...

为什么属性动画移动一个控件后,目标位置仍然能响应用户事件?

也就是说,应用了属性动画之后,该View依然可以正确地接收到事件的分派。

那就要搞清楚ViewGroup它是怎么找到这个"偷跑"了的View的。

我们知道,调用View的translationXX方法之后,虽然在屏幕上的位置是变了,但是它的[left,top,right,bottom]是不会变的。

来捋一遍ViewGroup分派事件的大致流程:

当手指按下时,触摸事件会经过ViewGroup中的dispatchTouchEvent方法筛选符合条件(手指在边界范围内)的子View进行分派事件(如果未被onInterceptTouchEvent拦截的话)。

那么,如果某个子View刚好应用了translation属性动画,在ViewGroup筛选子View时,直接判断触摸点是否在[left,top,right,bottom]范围内,是肯定不行的。

那它是怎么判断的呢?它会先调用子View的hasIdentityMatrix方法来判断这个View是否应用过位移、缩放、旋转之类的属性动画。

如果应用过的话,那接下来还会把触摸点映射到该子View的逆矩阵上(getInverseMatrix)。

判断处理后的触摸点,是否在该子View的边界范围内。

上面说到了"把触摸点映射到该子View的逆矩阵上",那它是怎么个映射法:

比如一个View它水平平移了200,那它所对应的逆矩阵就是水平平移了-200,

如果触摸点坐标是[500,500]的话,那么映射之后,就是[300,500],也就是反方向移动同样的距离了。

可以这样来理解:

如果一个View向右移动了一个拇指的距离,当手指在它的新位置上按下的时候,

(它最终还是要判断是否在原来的边界范围内的,那只能把触摸的坐标,给转回去,转回它应用变换之前的位置上),

那ViewGroup在检测到它应用了变换后,会把现在的触摸点,向左(刚刚是向右)移动一个拇指的距离(抵消),再来判断是否在该View的边界范围内。

那么为什么只有属性动画可以这样,补间动画就不行呢?

View在draw的时候,会检测是否设置了Animation(补间动画),

如果有的话,会获取这个动画当前的值(旋转或位移或缩放,透明度等),应用到canvas上,然后把东西draw出来。

比如设置了位移动画,当前值是向右移动了100,那么效果就等于这样:

Matrix matrix = new Matrix();

matrix.setTranslate(100, 0);

canvas.setMatrix(matrix);

它的作用只会在draw的时候有效。

虽然大家都是操作Matrix,但是Matrix的对象不一样(属性动画操作的Matrix,是View的mRenderNode所对应的Matrix),

所以在ViewGroup筛选的时候,应用属性动画的View会被正确找到,而补间动画的不行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值