http://blog.csdn.net/nieweilin/article/details/6053631

当一个Activity获得了焦点后,它将被要求去绘制它的layout(也就是那句在onCreate方法里面的setContentView()方法所设置的layout)。android的framework会处理这个绘制的过程,但是这个Activity也必须提供这个将绘制的View的layout层级的根节点信息。

ps:这里需要解释下最后一句话。我们都知道,一个layout文件是一个包含了多个层级的xml文件。里面的各个xml节点信息就代表了一个又一个的layout层级——也就是这里所谓的“layout层级的根节点”。借由xml技术的本身特点,我们可以保证每个层级在layout中的唯一性,如此一来,我们就可以很方便地为我们即将绘制于某layout上的View进行绘制部位定位了。另外学过数据结构的同学应该知道,节点是数据结构“树”中的概念。所以根据这个,我推测,layout的xml文件信息被加载到内存中后,实际上是以一个“树”的形式存在的。

绘制某个View的工作从该View即将绘制的layout根节点开始。framework在这之前会预测量和绘制这个layout“树”。而绘制该layout“树”的工作则会这么做:遍历这个“树”,然后为每个占有了某个未使用区域的View预留出某个已知大小(该大小就是我们常常用到的layout_width和layout_height属性中所包含的信息)的区域供以后绘制View时使用。之后,各个ViewGroup会依次请求将它们的子View被绘制(通过ViewGoroup的draw方法),而每个View在被绘制的时候又会调用它自身的onDraw方法来把自身绘制出来。因为layout“树”是按顺序遍历的,这就意味着父View(例如ViewGroup)会在子View之前被绘制。

tips:framework不会绘制那些不在未使用区域的View,而且它会为View绘制背景。你可以强制性的去让一个View被绘制——通过利用invalidate()方法。

ps:绘制一个完整的layout的步骤大致如下:1、将layout.xml文件解析至内存,让这些layout信息以一个“树”的形式存在。2、framework遍历该“树”,从上到下依次绘制View。3、绘制View时,会在未使用的区域为即将绘制的该View预留空间,接着调用该View的draw方法来绘制它。

绘制一个layout包含了两大过程:一个是尺寸测试过程。该过程中会在layout“树”里自顶向下地对每个View进行尺寸测量。尺寸测量的工作由View类的measure(int, int)方法进行实现。在"树"遍历的工程中,每个View会调用该方法,然后通过读取一些开发者设定的信息(layout_height layout_width)来保存自己的尺寸信息。当尺寸测试过程进入尾声时,每一个View都已经保存了它的尺寸信息了。另一个过程就是具体的绘制了。在这个自顶向下遍历树的绘制过程中,每个父View会调用layout(int, int, int, int)方法,并结合子View在尺寸测量过程中所保存的尺寸信息,来安放该子View在自己内部的位置。

当一个View的measure方法返回时,它的width和height——以及它的子View的——属性必须已经被设定完毕。一个View的width和height必须遵从它的父View的相关尺寸约束——这样就保证了在尺寸测试过程尾声时,所有的父View都能够顺利的接受它们的子View。一个父View可能会在其子View上多次调用measure方法。例如,父View可能会先调用它的子View的measure方法来得知它们究竟多大,进而好为它们预留绘制空间,然后父View有接着会又调用measure来测试是否该尺寸适合该View。

tips:通过调用requestLayout()可以初始化一个layout的相关信息。这个方法通常是View在发觉自己的当前所处范围不适合自己的当前情况时被主动调用。

在尺寸测试过程中,有两个类比较重要。一个是View.MeasureSpec。它被View用来告诉它的父View自己想要是多大以及如何地被放置。另一个是我们已经很熟悉的LayoutParams,它仅仅描述了这个View的height和width的信息。对于height和width,可以被如下指定:

1、一个确切的像素值

2、FILL_PARENT,这个意味着该height 或width和父View的相同(减去padding的像素值)。

3、WRAP_CONTENT,这个意味着该View的height和width以刚好包含其内容为准。

各个ViewGroup有自己相应的LayoutParams子类来实现各自个性化的设置需求。例如RelativeLayout有它自己的LayoutParams子类来设定其子View的相对位置。

MeasureSpecs被用来将父View的需求传递给子View。它可以被设置为以下三种模式之一:

  • UNSPECIFIED,父View对子View的尺寸大小没有特殊要求。
  • EXACTLY,父View需要把子View设置为某个特定的像素值。子View必须为这个值,而且要保证它的所有子View也在这个尺寸之内绘制。
  • AT_MOST,告诉子View一个最小的尺寸值。

更多相关文章

  1. Android更新Ui线程的四个方法
  2. Android获取本机IP地址(不是localhost)和MAC的方法
  3. Android 导入android源码有错,R.java文件不能自动生成解决方法
  4. Git,SVN使用方法杂记(更新中)
  5. 解决develop.android.com无法访问到最佳方法
  6. Android ActionBar使用方法(二)
  7. Android dex ,xml 文件反编译方法

随机推荐

  1. Android 中的图像特效(Matrix)
  2. Android(安卓)Monkey
  3. 【android 应用】Android(安卓)APP(应用)如何
  4. android获取控件宽高和屏幕宽高
  5. Fragment开发实例
  6. SVG使用
  7. 各种款式的别致的 Android 体恤衫
  8. Android 360开源全面插件化框架RePlugin
  9. Android下常见的内存泄露
  10. Android(安卓)-- Options Menu,Context M