在 Android 整个体系中,View 在其中扮演着不可或缺的角色。
前言
我对 Android 中的 View 理解是:View 在字面上面理解指的是视图,或者更加确切来说,它指的是控件,只不过这个控件的功能比较更广泛,没有像 Button
控件那样细化罢了。我为什么这么理解呢?因为在 View 体系中,例如 Button
、TextView
…它们都是继承自 View
,如 Android 5.0 源码中的:
1 | public class Button extends TextView |
1 | public class TextView extends View implements ViewTreeObserver.OnPreDrawListener |
在 Android 中,除了 View,还有 ViewGroup,ViewGroup 在字面上面的理解是:它指的是控件组。基于上面的 View 的解析,ViewGroup 便很好理解:ViewGroup 是多个控件的集合。也就是说,ViewGroup 它可以包含多个 View 控件,也是就可以解析下面的控件为什么可以包含多个子 View 了:
1 | public class LinearLayout extends ViewGroup |
1 | public class RelativeLayout extends ViewGroup |
1 | public class FrameLayout extends ViewGroup |
当然,ViewGroup 也是继承自 View:
1 | public abstract class ViewGroup extends View implements ViewParent, ViewManager |
1.0 View 的位置参数
在准备深入理解 View 体系的时候,需了理解 View 的一些细节,如 x
、y
、translationX
、translationY
等。在理解 View 的位置参数的时候,我们需要先弄清楚 View 中的 left
、right
、top
、bottom
所代表的含义是什么:
1 | /** |
则上面四个 left
、right
、top
、bottom
值通过上面的字面的理解,则可以通过作图表示为:
在 View 的源码中,存在着 left
、right
、top
、bottom
的获取接口,如下 Android 5.0 源码中:
1 | ... |
在 Android 的窗口中,存在着一个直角坐标系。这个直角坐标系可以这么理解的,以手机的左上角为原点,左上角水平向右为 X 轴,从左往右为正方向;左上角垂直向下为 Y 轴,从上到下为正方向,如上图的坐标系所示。一般地,这个坐标系是贯穿于 View 体系的,我们 Android 开发者应该熟知的。
弄清楚 left
、right
、top
、bottom
四个值的意义,那么 X
、Y
值的含义相对简单很多,如下源码:
1 | /** |
方法 getX()
返回的是一个单精度浮点型的值,又上面的源码可知,X
的值是 mLeft + getTranslationX()
的和,mLeft
的值是该 View 的左边缘距父 View 的左边缘的大小,而 getTranslationX()
又源码可知,
1 | /** |
getTranslationX()
的方法中,它是通过 mRenderNode.getTranslationX()
进一步的调用,返回对应的 View 的 translationX
值。在 View 中,translationX
值指的是该 View 据其自身的在 X 轴上的偏移量,默认值为 0px; 同理地,translationY
值指的是该 View 据其自身的在 Y 轴上的偏移量,默认值为 0px。通过做图更加清楚表示为:
现在理解了 translationX
,而 translationY
也是同样的原理可得,于是有源码可知,mLeft + getTranslationX()
相加的值为 X
,而 Y
则是 mTop + getTranslationY()
,于是 (X,Y)
便可以看作是 VIew 的左上角的原点,并且这个 (X,Y)
是随着 View 的移动而相对变化的。
理解了 left
、right
、top
、bottom
这四个参数的由来,对于 View 的 Width
和 Height
也是比较容易理解的了:
1 | width = mRight - mLeft; |
实质上,对于 View 的 Width
和 Height
在上面的解析,在 Android 5.0 的源码中也是如此的。并且 View 还提供了获取 Width
和 Height
的接口: getWidth()
和 getHeight()
有些时候,在自定义 View 的过程中,往往会遇到 rawX
和 rawY
这两个参数,如下面 kotlin 源码:
1 | class CustomSlidView: View { |
这个 CustomSlidView
实现的是一个可以自由拖动的 View,里面的 (rawX,rawY)
是指手指按下屏幕时的坐标点,这个坐标点是相对于 ``DecorView 而言的。(值得注意的是,
left、
right、
top、
bottom这四个值是相对于该 View 的父 View 的,而
(X,Y)` 是相对与自身的)
2.0 小总结
这一篇文章主要介绍了 View 的几个重要的位置参数。