原文:How Android Draws Views

当一个Activity获取到焦点的时候,它的布局就开始被绘制。

绘制的过程由Android framework处理。但布局层级的根节点必须由Activity提供。

视图的绘制由布局的根节点开始,通过遍历布局树和渲染每个和无效区域交叉的视图,整个布局和它的子布局(layout tree)都会被测量并绘制。反过来,ViewGroup的职责是请求它的每个子元素被绘制(通过draw()方法),而每个View的职责则是绘制它们自己本身。(意思是ViewGroup只负责排位,而view自己负责绘制工作)因为元素是 按顺序排列的,因此,父元素总是先于子元素被绘制,而父元素的同级别元素则按照它们出现的先后顺序绘制。

布局的绘制分为两个过程: 测量过程和布局过程.

测量过程在measure(int,int)方法中实现。它是按照view tree的排列从上到下进行测量的。在测量过程结束后,每个View都保存了自己的尺寸。

布局过程在layout(int, int, int, int)方法中实现,它也是从上而下进行的。在这个过程中,子元素的父节点根据子元素在上一个步骤中取得的值安排好它们的位置。

当一个View的measure()方法返回的时候,它的getMeasuredWidth()和getMeasuredHeight()的值必须被设置好。当View的父元素对这个子View的宽高值有限制的时候,这个子View必须遵守这个限制。这样做能保证在测量过程结束的时候,子View的宽高值能被父元素所接受。一个父View可能会对它的子View调用多次measure方法。举个例子,父View第一次调用measure()方法是为了获取子View请求的宽高,宽高值取得后,父View会根据这些值再次调用measure方法,进而检测这些值是否超出了限制(太大或是太小),如果是,则父View会在第二个过程中进行限制。

在测量过程中,子元素可以使用ViewGroup.LayoutParams类告知父元素它们所请求的尺寸。

ViewGroup.LayoutParams包含两个值:

MATCH_PARENT:子元素需要和父元素一样大(减去补白[padding])

WRAP_CONTENT:子元素只需要刚好能够放置它们的内容 (加上padding)

ViewGroup不同的子类有不同的LayoutParams。例如,RelativeLayout也有自己的LayoutParams类。

这使得RelativeLayout可以在水平和垂直方向上在中心放置子元素.

而父元素则可以通过MeasureSpec类限制子元素的尺寸。MeasureSpec的值可以是下面三个中的其中一个。

UNSPECIFIED:单纯用于获取子元素请求的值,不对子元素设置限制。例如:LinearLayout可以对它的子元素的长和宽分别设置为UNSPECIFIED和EXACTLY的值为240,这样可以知道当给子元素的长是240px的时候,它所需要的高度度会是多少。

EXACTLY:父元素将子元素的值限制为指定的值。子元素必须使用这个值,并且保证它的所有后代元素在这个尺寸内可用。

AT_MOST:父元素指定子元素的最大尺寸。子元素必须保证它和它的所有后代元素在这个尺寸内可用。

注意:Android framework不会绘制不在无效区域的View,但是依然会负责绘制View的背景。

我们可以通过调用invalidate()方法强制一个View重新绘制。

通过调用requestLayout()初始化布局。当一个View对象认为现在的区域已经无法正常工作的时候就会调用这个方法。

关于有效区域和无效区域:无效区域是需要被更新的区域,有效区域无须被更新。

有windows 开发经验的人都应该知道,当一个窗口从被遮挡到出现,窗口会重新被绘制,而这个被遮挡的区域就是无效区域。因为当这个区域再次出现的时候,我们必须保证它的内容是最新的,因此需要被更新,即重新绘制.

有效区域之所有被称为有效区域,是因为它目前的状态已经是最新的,不需要更新,所以不需要被重绘。

[翻译] Android是怎样绘制视图的的更多相关文章

  1. 理解Android绘制视图的方式

    在创建自定义ViewGroup前,读者首先需要理解Android绘制视图的方式.我不会涉及过多细节,但是需要读者理解Android开发文档(见3.5节)中的一段话,这段话解释如何绘制一个布局.内容如下 ...

  2. Android之View绘制流程源码分析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于稍有自定义View经验的安卓开发者来说,onMeasure,onLayout,onDraw这三个方法都不会陌生,起码多少都有所接触吧. 在安卓中 ...

  3. Android中View绘制流程以及invalidate()等相关方法分析

    [原文]http://blog.csdn.net/qinjuning 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简 ...

  4. Android View的绘制机制流程深入详解(三)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第三篇主要介绍并分析视图状态以及重绘流程,首先剖析了 视图的几种状态,然后在深入分析视图的重绘机制流程. 真题园网:http://w ...

  5. Android View的绘制机制流程深入详解(二)

    本系列文章主要着重深入介绍Android View的绘制机制及流程,第二篇主要介绍并分析Android视图的绘制的原理和流程.主要从 onMeasure().onLayout()和onDraw()这三 ...

  6. Android中View绘制流程以及invalidate()等相关方法分析(转载的文章,出处在正文已表明)

    转载请注明出处:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时 ...

  7. android之View绘制

    Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类,由此就得到了视图部分的基本结构--树形结构 View定义了绘图的基本 ...

  8. Android笔记--View绘制流程源码分析(一)

    Android笔记--View绘制流程源码分析 View绘制之前框架流程分析 View绘制的分析始终是离不开Activity及其内部的Window的.在Activity的源码启动流程中,一并包含 着A ...

  9. Android中View绘制流程以及invalidate()等相关方法分析(转)

    转自:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴 ...

随机推荐

  1. 《高性能javascript》 领悟随笔之-------DOM编程篇(二)

    <高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  2. linux系统编程之进程(二):进程生命周期与PCB(进程控制块)

    本节目标: 进程状态变迁 进程控制块 进程创建 进程撤消 终止进程的五种方法 一,进程状态变迁 进程的三种基本状态 就绪(Ready)状态 当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便 ...

  3. Java设计模式 -- 基本原则

    这两个星期开始系统地学习设计模式相关的知识,对每一个原则或者设计模式主要从下面几点分析学习: 定义:简单地描述其作用 解决问题:说明该原则或设计模式解决什么限制条件下的问题. 结构图:绘制相关例子的U ...

  4. 如何用CSS画三角形

    很多时候页面都需要一个或者多个小型三角形!多数人直接用PS扣个图片预览 下面用CSS简单画几个最终效果如下图 <div class="border-all-color"> ...

  5. 怎样给div增加resize事件

    当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件,这个事件在window上面触发,那么如何给div元素增加resize事件,监听div的高度或宽度的改变呢? 先来回答另一个问题,监听 ...

  6. 强大的observejs

    写在前面 各大MVVM框架的双向绑定太难以观察,很难直观地从业务代码里知道发生了什么,我不是双向绑定的反对者,只是认为双向绑定不应该糅合进底层框架,而应该出现在业务代码中,或者是业务和框架之间的代码上 ...

  7. 移动端图片随手势移动react组件(附移动开发小tips)

    这个效果是公司产品中一个用到的效果,用于展示项目的信息,废话少说,先上效果图,代码在最后:),这个组件是在上篇博客中用webpack搭建的环境中完成的http://www.cnblogs.com/wu ...

  8. JDBC数据库访问操作的动态监测 之 p6spy

    P6spy是一个JDBC Driver的包装工具,p6spy通过对JDBC Driver的封装以达到对SQL语句的监听和分析,以达到各种目的. P6spy1.3 sf.net http://sourc ...

  9. 利用NetworkExtension库配置VPN

    VPN简单说就是连接局域网的一个通道.Ios8之后苹果增加了一个VPN的接口NEVPNManager,它可以方便的添加VPN连接. 首先在你的Xcode内,TARGETS->Capabiliti ...

  10. Google C++单元测试框架GoogleTest---GMock的CheatSheet文档

    CheatSheet文档中包含了GMock所有常用的东西,看了这个基本上就可以用它了,本文接上篇博文:Google C++单元测试框架GoogleTest---Google Mock简介--概念及基础 ...