1、介绍
在平面图形中,图形都是由点坐标确定的。同样,Android的设备屏幕也是一个,如果非3D图形,正常的view就是一个二维坐标
屏幕的左上角的坐标A(0,0),如果屏幕的宽为:width,高:height 那么右下角的坐标是D(width,height)
坐标的顶点从A点,向右和向下两个方向延伸。所有横坐标为X轴,中坐标是Y轴,变成坐标
D(x,y)=D(width,height)
二、分析
通过上面的介绍,我们知道了屏幕中坐标点的基本逻辑与知识。很多人在使用中,发现获取坐标点与理想的不一致。通过view.getX()或者view.getY()。
有人会疑问:
getPivotX()和getPivotY()不也是坐标嘛?其实这个与getX()和getY()是有区别的,
(getPivotX(),getPivotY())是旋转中心点的坐标
(getX(),getY())点坐标
坐标点分类:
坐标点分为两大类,一种是在父控件中的绝对坐标点,还有一个是屏幕。
1.父控件:
获取(getX(),getY()),其实就是获取在父控件的坐标
如上图,根布局点A(0,0)的坐标,B是子布局(10,10),C(10,10)是子布局的子布局,三层嵌套。
相对根布局来说,其实C在屏幕中的坐标应该是(20,20),这是通过获取ViewC在屏幕中的坐标,如果是(10,10),就是在父控件中的坐标
涉及屏幕坐标:
1、getLocationInWindow:
计算此视图在其窗口中的坐标。参数必须是一个由两个整数组成的数组。方法返回后,数组将按顺序包含x和y位置
2、getLocationOnScreen:
计算此视图在屏幕上的坐标。参数必须是一个由两个整数组成的数组。方法返回后,数组将按顺序包含x和y位置。
3、getLocationInSurface:
计算视图在曲面内的坐标。计算此视图在其曲面中的坐标。参数必须是一个由两个整数组成的数组。方法返回后,数组将按顺序包含x和y位置
注意:
屏幕坐标相对根布局坐标存在误差,X轴是相同的,但是Y轴会有误差,这个误差的距离是顶部状态栏的高度。
如何获取真实高度,用获取到屏幕中的坐标减去状态栏的高度。
状态栏高度获取:
var f = Rect()
window.decorView.getWindowVisibleDisplayFrame(f)
var statusBarHeight=f.top
获取view在屏幕中的坐标:
var locationWindow = IntArray(2)
bind.img.getLocationInWindow(locationWindow)
MyLog.log("坐标----getLocationInWindow", "${locationWindow[0]},${locationWindow[1]}")
View在根布局真实的坐标:
var locationWindow = IntArray(2)
bind.img.getLocationInWindow(locationWindow)
var f = Rect()
window.decorView.getWindowVisibleDisplayFrame(f)
var trueY=locationWindow(1)-f.top
计算出Y轴的真是坐标,(locationWindow(0),trueY)
注意:
第一点:
正常窗口是两种,一种是全屏,另外一种是有状态栏。如果你当前的Activity是全屏,那么获取到的窗口坐标就是View的坐标。即使你通过window获取状态栏也是为0 。
第二点:
getLocationInWindow,getLocationOnScreen,getLocationInSurface,这三个获取的坐标可能会随着屏幕发生改变而改变。
如何测试?
我们可以通过shell命令修改屏幕大小来观察
如何修改屏幕显示大小:
第一步:adb shell,进入shell
第二步:wm size,查看当前设备的尺寸
第三步:wm size 360x480,修改屏幕是360x480,这里x不能通过*来代替。
第四步:wm size reset,还原设备到原来的尺寸,或者指定原尺寸大小也可以
如果设置分辨率出现以下情况:
可以在开发者中,开启USB调试(安全设置)
通过以上的测试,可以看出坐标随着屏幕发生的变化。如果修改完,发现launch无法启动,可能你的launch出现了BUG,黑屏,只能操作底部的导航(SystemUI),需要重新启动设备。
动画与坐标
通过上面的坐标学习,我们现在可以很清楚的知道了坐标在不同view中的真是数据。为什么要讲坐标?
坐标对于动画来说至关重要,为什么这么说?如果获取不到真实的数据,那么动画就达不到想要的目的,影响用户体验。通过以上学习,可以帮助动画找到真实的数据。