Android View的坐标系
Android View的坐标系
Android View的坐标系是一个三维直角坐标系,其中X轴正方向向右,Y轴正方向向下,Z轴正方向则是垂直于屏幕向上。这和通常的三维直角坐标系并不相同,通常的三维直角坐标系是Y轴向上的右手坐标系,而Android View的坐标系则是一个Y轴向下的左手坐标系。如图所示。
由于这里只讨论Android View的坐标系,后文会将Android View的坐标系简称为Android坐标系。但需要知道的是,Android坐标系除了Android View的坐标系之外,还有其他的坐标系。例如传感器坐标系,OpenGL ES坐标系等。
Android坐标系的坐标原点
在Android坐标系中坐标原点的选取至关重要。屏幕中同样的位置,选择不同的的坐标原点会得到不同的坐标。一般来说把坐标原点放在屏幕左上角的坐标系称为绝对坐标系(即上图中所示的坐标系),把坐标原点放在其他位置的坐标系称为相对坐标系。后文中会对坐标原点的选取做更仔细的分析。
Android View的坐标
这里先说明一点,在Android坐标系中,只有和View关联起来的点的坐标和距离才有意义,例如一个View左上角的坐标,中心点的坐标,View左边线到Y轴的距离等。脱离View谈论坐标和距离是没有意义的。
在Android坐标系中,一个View中某个点的X轴和Y轴的坐标表示的是该点在对应坐标轴的投影到坐标原点的距离(也是通常意义上的坐标的定义),以像素为单位。但是由于屏幕是二维的,View中点并不能显示在屏幕外,所以Z轴的坐标并非表示该点在Z轴的投影到坐标原点的距离,而是表示该View的Z序(Z order)。
关于Z序,有如下几点需要了解。
- Z序表示的同一个Parent(Layout)中,层叠在一起的View的显示顺序。在同一个Layout中,如果有两个View的位置存在重叠,则Z序大的会显示在前面,Z序小的显示在后面,也就是说在两个View的重叠区域看到的将是Z序较大的View。
一个View的Z序只有在其Parent中才有意义,比较不同Parent中View的Z序是没有意义的。
例如有如下布局,view1和view2并不在同一个parent中,view1的parent是layout1,view2的parent是layout2,所以比较view1和view2的Z序是没有意义的。即使view1的Z序大,view1也不能显示在view2上面。但是view1和layout2有同一个parent,所以可以比较view1和layout2的Z序。如果view1相比layout2的Z序大,则view1会显示在layout1前面,这时无论view2的Z序是多少,view1都会覆盖在view2的上面。<RelativeLayout android:id="@+id/layout1" android:layout_width="wrap_content" android:layout_height="wrap_content"> <View android:id="@+id/view1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <FrameLayout android:id="@+id/layout2" android:layout_width="wrap_content" android:layout_height="wrap_content"> <View android:id="@+id/view2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </FrameLayout> </RelativeLayout>
Z序是View的一个属性,同一个View中所有的点都有相同的Z序,而同一个View中不同点的X,Y的坐标是可以不一样的。
在Android 5.0之前的版本中,一个Layout中的View遵循自然Z序,也就是View的Z序等于它们在XML中定义的顺序。一个Layout中最先定义的View的Z序为0,之后依次加1。如果是通过代码添加的View,执行addView()时可以通过其index参数指定添加后View的Z序,如果不指定,则同样按照自然顺序,在上次View的Z序基础上加1。
例如有如下布局,layout1是根View,它在其Parent中(即使是Activity的根Layout也有一个DecoView的Parent)的Z序为0,layout2是layout1中最先定义的View,其Z序为0。view1是layout2中最先定义的View,其Z序为0,view2的Z序则为1。view3和layout2同级,其Z序也为1。为layout2执行addView()添加一个新的View,并且不指定index,则新的View的Z序为2。
<RelativeLayout android:id="@+i