文章目录
I . View 坐标体系总结
- II . View 组件的 left , top , right , bottom 父容器相对位置
- III . View 组件的 x , y , translationX , translationY 属性
- IV . View 组件 窗口坐标 属性
- V . View 组件 屏幕坐标 属性
- VI . View 组件的触摸位置 属性
- VII . View 坐标获取 0 的解决方案
I . View 坐标体系总结
left , top , right , bottom 是组件相对于父容器的位置 , 该值一般不会改变 ;
x , y 是组件当前相对于父容器的位置 ;
translationX , translationY 分别是相对于 left , top 值的偏移大小 ;
left translationX = x , top translationY = y ;
窗口坐标获取 : getLocationInWindow ;
屏幕坐标获取 : getLocationOnScreen ;
触摸坐标 : x , y 触摸坐标是相对于组件的坐标 , rawX , rawY 是相对于屏幕的坐标 ;
II . View 组件的 left , top , right , bottom 父容器相对位置
1 . View 组件的基础位置 : left , top , right , bottom 是 View 组件的最基本的位置属性 , 其作用是 描述该组件相对于父容器的位置 ;
2 . 相对父容器位置 : 这里特别注意 , left , top , right , bottom 属性 , 是 相对于父容器的位置 , 不是 相对于 Activity 界面位置 , 也不是 相对于屏幕的位置 ;
3 . 属性本质 : left , top , right , bottom , 四个属性本质是坐标值 ;
4 . 父容器 坐标系 及 坐标原点 : 四属性的坐标值原点
是父容器的左上角位置 ,
轴向右为正 , 向左为负 ,
轴向下为正 , 向上为负 ;
5 . 组件基础位置属性 : 组件的基础位置属性是不会改变的 ;
① left 属性 : 组件的左侧
轴坐标 , 值为左侧距离父容器左侧的长度 , 本组件左上角顶点 , 在父容器坐标系的
值 ;
② top 属性 : 组件的顶部
轴坐标 , 值为顶部距离父容器顶部的高度 , 本组件左上角顶点 , 在父容器坐标系的
值 ;
③ right 属性 : 组件的右侧
轴坐标 , 值为右侧距离父容器左侧的长度 , 本组件右下角顶点 , 在父容器坐标系的
值 ;
④ bottom 属性 : 组件的底部
轴坐标 , 值为底部距离父容器顶部的长度 , 本组件右下角顶点 , 在父容器坐标系的
值 ;
III . View 组件的 x , y , translationX , translationY 属性
1 . View 组件的当前位置 : x , y , translationX , translationY 是 View 组件的当前位置 , 其作用是 描述当前的实际位置 , 该位置也是相对于父容器的坐标 , 这里要与基础位置区分开 ;
2 . 组件当前位置 属性 : x , y 是当前的位置 , 这个位置会随着 translationX 和 translationY 的值改变而改变 ;
① x : 表示组件左上角当前的实际位置的 x 坐标 , 该坐标是父容器坐标系中的坐标 , 原点是父容器左上角位置 ;
② y : 表示组件左上角当前的实际位置的 y 坐标 , 该坐标是父容器坐标系中的坐标 , 原点是父容器左上角位置 ;
3 . 偏移位置 : translationX , translationY , 是基于基础位置 left , top 的偏移位置 ;
4 . 当前位置 和 偏移位置 的 初始值 : x 的初始值是 left , y 的初始值是 top , translationX 初始值是 0 , translationY 初始值是 0;
5 . View 组件 坐标属性之间的关系 :
① x , left , translationX 关系 :
② y , top , translationY 关系 :
6 . 代码分析 :
① View 组件获取 x 属性代码分析 : x 的值 , 由 left 加上 translationX 得到 ;
代码语言:javascript复制/**
* The visual x position of this view, in pixels. This is equivalent to the
* {@link #setTranslationX(float) translationX} property plus the current
* {@link #getLeft() left} property.
*
* @return The visual x position of this view, in pixels.
*/
@ViewDebug.ExportedProperty(category = "drawing")
public float getX() {
return mLeft getTranslationX();
}
② View 组件获取 y 属性代码分析 : y 的值 , 由 top 加上 translationY 得到 ;
代码语言:javascript复制/**
* The visual y position of this view, in pixels. This is equivalent to the
* {@link #setTranslationY(float) translationY} property plus the current
* {@link #getTop() top} property.
*
* @return The visual y position of this view, in pixels.
*/
@ViewDebug.ExportedProperty(category = "drawing")
public float getY() {
return mTop getTranslationY();
}
IV . View 组件 窗口坐标 属性
1 . 获取 View 组件窗口坐标 : 这里的窗口指的是 Activity 窗口 ;
① 所在坐标系 : 坐标系的原点
是 Activity 窗口的左上角位置 ;
② 区分屏幕坐标 : Activity 窗口上还有一个状态栏 , 这里要与屏幕坐标系区分开 ;
③ 获取方法 : 调用 View 组件对象的 getLocationInWindow ( ) 方法 , 数组 0 索引是 x 坐标 , 数组 1 索引是 y 坐标 ;
代码语言:javascript复制int[] array = new int[2];
surfaceView.getLocationInWindow(array);
V . View 组件 屏幕坐标 属性
1 . 获取 View 组件屏幕坐标 : 这里的屏幕指的是手机屏幕 ;
① 所在坐标系 : 坐标系的原点
是 手机屏幕的左上角位置 ;
② 获取方法 : 调用 View 组件对象的 getLocationOnScreen ( ) 方法 , 数组 0 索引是 x 坐标 , 数组 1 索引是 y 坐标 ;
代码语言:javascript复制int[] array = new int[2];
surfaceView.getLocationOnScreen(array);
VI . View 组件的触摸位置 属性
View 组件的触摸事件的位置属性 :
① x , y 相对于组件坐标 : 当触摸组件时 , 从 MotionEvent 事件中获取的 x , y 坐标是 相对于本组件的坐标 , 即坐标系的原点
是该组件的左上角位置 ;
② rawX , rawY 相对于屏幕坐标 : 从 MotionEvent 事件中获取的 rawX , rawY 坐标 , 是当前触摸点相对于屏幕的坐标 , 即坐标系的原点
是屏幕的左上角位置 ;
VII . View 坐标获取 0 的解决方案
1 . 问题描述 : 在获取组件 位置 , 宽高 时 , 经常遇到获取组件的值为
的情况 , 这是因为该组件还没有绘制完成 ;
2 . 解决方案 : 获取 ViewTreeObserver , 监听布局树的绘制情况 , 组件绘制时 , 需要测量 ( Measure ) , 摆放 ( Layout ) , 绘制 ( Draw ) , 此时监听的是摆放操作 , 摆放完毕后 , 就可以获取组件的坐标和大小属性 ;
3 . 监听 Layout 代码 :
代码语言:javascript复制surfaceView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//此时可以获取 View 的坐标和大小 , 不为 0
}
});