自定义View(一)—— 坐标系

1. 坐标系

1.1. 数学的坐标系和屏幕坐标系

image-20230703234028826

在数学当中,我们常见的坐标系是如上图这样,x轴和y轴分别自左至右和自下而上延伸,角度是以逆时针方向为正

但是Android的屏幕和这会有一些区别

image-20230704001143588

在Android设备的屏幕上,x轴和y轴是分别向右和向下的,设备屏幕的左上角是坐标系的坐标原点,角度以顺时针旋转方向为正

1.2. View的坐标系

View的坐标系是相对于它的父级而言的

image-20230704234121119

topbottomleftright分别是与View的位置表示相关的概念,描述的是其在父级中的相对位置

The geometry of a view is that of a rectangle. A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the pixel.

View实质上表述的是一个矩形范围,关于其位置的确定,使用的是其左上角的坐标,就像这里的topleft,在该坐标系下,确定其左上角的坐标位置,其实再配合另外2个维度,即宽、高就可以确定这个View具体表示的范围了

通过对于View对象调用getLeft()getTop()可以得到lefttop的值,即View(矩形)的坐标(x, y),需要注意的是,返回的数值是相对于父级View的,并且默认单位为像素

除此以外,View还提供了getRight()getBottom()方法来获取所谓rightbottom的数值,其实right = left + widthbottom = top + height,只是简化了部分计算,可能更加直观一些,在实际的自定义View的编码过程中,这些概念是非常常用的,也经常作为一些方法的参数被用到,因此熟悉这些概念很有必要

1.3. MotionEvent中的坐标

在处理Android设备上的各种触屏事件,我们不免会接触到一个MotionEvent类,它用于描述移动(通常接触屏幕的是手指),通过一些参数来描述这样的事件

Object used to report movement (mouse, pen, finger, trackball) events. Motion events may hold either absolute or relative movements and other data, depending on the type of device.

我们的手指接触到设备的屏幕,就会产生事件,而整个设备的屏幕就是一个大的坐标系,而我们手指接触的位置便是这个坐标系中的某个特定的点,对应的便是一个MotionEvent对象

image-20230707231946669

getX()getRawX()均是MotionEvent对象的方法,前者获取的是当前事件对象与当前View的左边界的水平相对距离,而后者获取的是事件对象与屏幕左边界的水平距离

当然,对应地也有getY()getRawY()

前者可以看做是将事件所在View以左上角为左边原点,作一个坐标系,将MotionEvent对象的位置表示出来,而后者则是将整个屏幕作为坐标系,如果将MotionEvent看做一个不计大小的View,那么正好可以分别对应View的坐标系与屏幕坐标系来看待

image-20230707232916681