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会被正确找到,而补间动画的不行。
属性动画所影响的Matrix,是在View的mRenderNode中的stagingProperties里面的,这里的Matrix,每个View之间都是独立的,所以可以各自保存不同的变换状态。
而补间动画,它所操作的Matrix,其实是借用了它父容器的一个叫mChildTransformation的属性(里面有Matrix),通过getChildTransformation获得。
也就是说,一个ViewGroup中,无论它有几个子View都好,在这些子View播放补间动画的时候,都是共用同一个Transformation对象的(也就是共用一个Matrix),这个对象放在ViewGroup里面。
有同学可能会问:共用?不可能吧,那为什么可以同时播放好几个动画,而互相不受影响呢?
是的,在补间动画更新每一帧的时候,父容器的mChildTransformation里面的Matrix,都会被reset。

每次重置Matrix而不受影响的原因:

是因为这些补间动画,都是基于当前播放进度,来计算出绝对的动画值并应用的,保存旧动画值是没有意义的。
就拿位移动画TranslateAnimation来说,比如它要向右移动500,当前的播放进度是50%,那就是已经向右移动了250,在View更新帧的时候,就会把这个向右移动了250的Matrix应用到Canvas上,当下次更新帧时,比如进度是60%,那计算出来的偏移量就是300,这时候,已经不需要上一次的旧值250了,就算Matrix在应用前被重置了,也不影响最后的效果。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351