View.transform 与 View.scroll 与 Canvas.transform


View.transform 代表了:
android.view.View.setTranslationX::float:
android.view.View.setTranslationY::float:
android.view.View.setTranslationZ::float:
android.view.View.setRotation::float:
android.view.View.setRotationY::float:
android.view.View.setRotationX::float:
android.view.View.setScaleX::float:
android.view.View.setScaleY::float:
这些对视图的变形操作,Canvas.transform 也能代表这么多变形操作。

View.transform 与 View.scroll 的区别与联系:

  1. View.transform 是将视图本身移动,View.scroll 则是视图本身不动,所有的子视图移动
  2. 在感觉上 View.transform 与 View.scroll 的移动方向是反的,如View.setTranslationX(100)是视图本身向右移动100,View.setScrollX(100) 是所有子视图向左移动100。
  3. View.transform 的值存在native层,View.scroll的值存在java层。
  4. View.transform 不影响视图本身的 layout,View.scroll 会在感受上影响子视图的 layout 位置。
  5. View.transform 与 View.scroll 的一个相同点是它们都会影响 MotionEvent,也就是所有的 MotionEvent 在分发的时候都要经过 scroll 与 transform 这两种变形移位,因此视图接收点击事件的范围会跟着视图的变形一起变化。有函数为证:
	android.view.ViewGroup.transformPointToViewLocal::float,View:src
    /**
     * @hide
     */
    public void transformPointToViewLocal(float[] point, View child) {
        point[0] += mScrollX - child.mLeft;
        point[1] += mScrollY - child.mTop;
        if (!child.hasIdentityMatrix()) {
            child.getInverseMatrix().mapPoints(point);
        }
    }

这里的 child.getInverseMatrix() 获得的 Matrix 就是 记录View.transform变形的矩阵 的逆矩阵。这个矩阵也是从 native 层取出来的。

View.transform 与 Canvas.transform 的区别与联系:

  1. View.transform 会影响点击事件,意思是视图接收点击事件的范围会跟着视图的变形一起变化,Canvas.transform 不会,因此对 Canvas 变形前都会先使用 save 函数保存原来的状态,等绘制完了再使用 restore 函数恢复原来的状态,以免让你有视图接收不到点击事件的感觉(这种感觉是因为视图的事件接收范围与显示范围不一致造成的)。
  2. 这两种变形都不会影响 layout,View.transform 会影响点击事件,让你感觉视图不仅是显示发生了变化,而且布局也变化了,但其实没有

Canvas.transform 与 View.transform 与 View.scroll 的联系:

View.transform 与 View.scroll 的效果都是通过 Canvas.transform 来实现的,具体实现过程看函数android.view.View.draw::Canvas,ViewGroup,long:。这也解释了 View.transform 为什么没有影响布局。
那 View.scroll 为什么会影响子视图的布局呢,其实本质上它也没有让子视图的布局移位,只是它绘制子视图(dispatchDraw)之前将整个 Canvas 向前移位了,子视图绘制结束后它又使用函数 restore 将 Canvas 恢复了(向后移位),因此有了子视图的布局被整体后移的感觉

关于布局多说一句

存放视图布局的数据结构只有mLeft,mRight,mTop,mBottome 这四个值,因此它不可能给视图带来丰富的变形功能,因此视图的形变没有通过 layout 来实现(通过 layout 顶多可以实现视图平移,但为了统一,平移的功能也没有用 layout 实现),而是使用 Canvas.transform 来实现,也因此 View.transform 绝不会影响 layout

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值