Android - View的绘制流程一(measure)
该博文所用的demo结构图:

- <span style="font-family:Microsoft YaHei;">public class MainActivity extends Activity {
- private int desiredWindowWidth;
- private int desiredWindowHeight;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //获取屏幕的宽高,单位为dp
- desiredWindowWidth = Measurement.getScreenWidth(this);
- desiredWindowHeight = Measurement.getScreenHeight(this);
- Log.d("HWGT", "屏幕宽..=.." + desiredWindowWidth + "....屏幕高..=.." + desiredWindowHeight);
- }
- @Override
- protected void onPause() {
- super.onPause();
- //获取状态栏的高度(标题栏+content区域的top坐标)
- Rect frame = new Rect();
- getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
- int statusBarHeight = Measurement.px2dip(this, frame.top);
- //获取 标题栏+content 区域的高度
- int titleAndContentHeight = Measurement.px2dip(this, frame.height());
- //获取content区域的top坐标
- int tempContentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
- int contentTop = Measurement.px2dip(this, tempContentTop);
- //标题栏的高度 = content区域的top坐标 - 状态栏的高度
- int titleBarHeight = contentTop - statusBarHeight;
- Log.d("HWGT", "titleBarHeight..=.."+titleBarHeight+
- "....contentTop..=.."+contentTop+"....statusBarHeight..=.." + statusBarHeight );
- }
- }</span>
activity_main.xml:
- <span style="font-family:Microsoft YaHei;"><com.hwgt.drawingprocessofview.ui.MyCustomLinearLayoutA
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context="com.hwgt.drawingprocessofview.MainActivity" >
- <com.hwgt.drawingprocessofview.ui.MyCustomTextViewA
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="13dp"
- android:layout_gravity="center_horizontal"
- android:text="@string/hello_world" />
- <com.hwgt.drawingprocessofview.ui.MyCustomLinearLayoutB
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="13dp">
- <com.hwgt.drawingprocessofview.ui.MyCustomButtonA
- android:layout_width="111dp"
- android:layout_height="wrap_content"
- android:layout_marginLeft="31dp"
- android:text="@string/ok"/>
- </com.hwgt.drawingprocessofview.ui.MyCustomLinearLayoutB>
- </com.hwgt.drawingprocessofview.ui.MyCustomLinearLayoutA></span>
Measurement.java:
- <span style="font-family:Microsoft YaHei;">public class Measurement {
- public static int px2dip(Context context, float pxValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (pxValue / scale + 0.5f);
- }
- public static int getScreenWidth(Context context) {
- WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics dm = new DisplayMetrics();
- manager.getDefaultDisplay().getMetrics(dm);
- return px2dip(context, dm.widthPixels);
- }
- public static int getScreenHeight(Context context) {
- WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics dm = new DisplayMetrics();
- manager.getDefaultDisplay().getMetrics(dm);
- return px2dip(context, dm.heightPixels);
- }
- }</span>
MyCustomLinearLayoutA.java、MyCustomTextViewA.java、MyCustomLinearLayoutB.java 和 MyCustomButtonA.java类似,构造函数省略了,onMeasure()方法中的处理也一样:
- <span style="font-family:Microsoft YaHei;">public class MyCustomLinearLayoutA extends LinearLayout ... ...
- public class MyCustomTextViewA extends TextView ... ...
- public class MyCustomLinearLayoutB extends LinearLayout ... ...
- public class MyCustomButtonA extends Button {
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int widthMeasureSpecSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightMeasureSpecSize = MeasureSpec.getSize(heightMeasureSpec);
- Log.d("HWGT", "ButtonA: widthMeasureSpecSize..=.."+Measurement.px2dip(getContext(), widthMeasureSpecSize)
- + "....heightMeasureSpecSize..=.."+Measurement.px2dip(getContext(), heightMeasureSpecSize));
- }
- }</span>
的 setContentView()方法
--> generateDecor()方法创建一个DecorView(FrameLayout的子类)对象 mDecor
该方法主要逻辑为:
和 R.layout.screen_simple
- <span style="font-family:Microsoft YaHei;"><LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:fitsSystemWindows="true">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="?
android:attr/windowTitleSize"
- style="?android:attr/windowTitleBackgroundStyle">
- <TextView
- android:id="@android:id/title"
- style="?android:attr/windowTitleStyle"
- android:background="@null"
- android:fadingEdge="horizontal"
- android:gravity="center_vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </FrameLayout>
- <FrameLayout
- android:id="@android:id/content"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:foregroundGravity="fill_horizontal|top"
- android:foreground="?android:attr/windowContentOverlay" />
- </LinearLayout></span>
R.layout.screen_simple:
- <span style="font-family:Microsoft YaHei;"><FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/content"
- android:fitsSystemWindows="true"
- android:foregroundInsidePadding="false"
- android:foregroundGravity="fill_horizontal|top"
- android:foreground="?android:attr/windowContentOverlay" /> </span>
name="android:windowNoTitle">true</item>时。R.layout.screen_simple将被加入到mDecor中。
布局加入到 mContentParent 中。

紫色框代表根view -- mDecor

(该图截取自Android内核剖析一书,谢谢作者)
- - DecorView開始的
lp.height);
(一般为 MATCH_PARENT)

一个measurespec封装了父视图对子视图在长度或宽度上的要求。一个measurespec由大小和模式组成(使用makeMeasureSpec方法获取)。
UNSPECIFIED:代表父视图对子视图在长度或宽度上不施加不论什么约束。子视图能够是不论什么它想要的大小
(代码经简化,仅为理解大致流程)
measureChildWithMargins(child, ... ... ) 方法(定义在ViewGroup类中)
—— 向mDecor里加入的窗体布局(图一中为R.layout.screen_simple,图二中为R.layout.screen_title)的measure方法得到运行,再在R.layout.screen_simple或R.layout.screen_title的onMeasure方法中进行遍历,运行到id为content的布局相应的measure方法,...
... ,直到该博文demo中的MyCustomLinearLayoutA的measure和onMeasure方法。

- <span style="font-family:Microsoft YaHei;">protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (mOrientation == VERTICAL) {
- measureVertical(widthMeasureSpec, heightMeasureSpec);
- } else {
- measureHorizontal(widthMeasureSpec, heightMeasureSpec);
- }
- }</span>
{
== 0 ? mTotalLength : 0 。这里跳过了weight>0的子视图。所以值为mTotalLength(在对MyCustomTextViewA进行measure时。值为0。另外,測量的是竖直方向。所以第4个參数直接传入0)
i, widthMeasureSpec, 0, heightMeasureSpec,totalWeight == 0 ? mTotalLength : 0);
heightMeasureSpec,int totalHeight) {
int widthUsed,
即 MyCustomTextViewA 的布局參数
— id为content的布局传递来的WidthMeasureSpec
和 MeasureSpec.getMode 得到对应的size和mode(360dp MeasureSpec.EXACTLY)
这三项进行相加
的本身尺寸之外 全部空间的总和
第三个參数:child的width值(childHeightMeasureSpec 同理)
的本身尺寸之外 全部空间的总和
的 MeasureSpec
改为"wrap_content"或详细的一个dp值
和 mMeasuredHeight 的过程。
— draw了。
Android - View的绘制流程一(measure)的更多相关文章
- Android View的绘制流程
写得太好了,本来还想自己写的,奈何肚里墨水有限,直接转吧.正所谓前人种树,后人乘凉.. View的绘制和事件处理是两个重要的主题,上一篇<图解 Android事件分发机制>已经把事件的分发 ...
- android view的 绘制流程
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 首先是 从 视图根 这个类的 进行遍历 performTraversals 方法 开 ...
- Android View 的绘制流程之 Layout 和 Draw 过程详解 (二)
View 的绘制系列文章: Android View 的绘制流程之 Measure 过程详解 (一) Android View 绘制流程之 DecorView 与 ViewRootImpl 在上一篇 ...
- 每日一问:简述 View 的绘制流程
Android 开发中经常需要用一些自定义 View 去满足产品和设计的脑洞,所以 View 的绘制流程至关重要.网上目前有非常多这方面的资料,但最好的方式还是直接跟着源码进行解读,每日一问系列一直追 ...
- 深入理解 Android 之 View 的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- Android探究之View的绘制流程
Android中Activity是作为应用程序的载体存在,代表着一个完整的用户界面,提供了一个窗口来绘制各种视图,当Activity启动时,我们会通过setContentView方法来设置一个内容视图 ...
- Android的自定义View及View的绘制流程
目标:实现Android中的自定义View,为理清楚Android中的View绘制流程“铺路”. 想法很简单:从一个简单例子着手开始编写自定义View,对ViewGroup.View类中与绘制View ...
- 【转】深入理解Android之View的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- Android之View的绘制流程
本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定实现细 ...
- Android View的绘制机制流程深入详解(四)
本系列文章主要着重深入介绍Android View的绘制机制及流程,第四篇主要介绍Android自定义View及ViewGroup的实现方法和流程. 主要介绍了自绘控件.自定义组合控件.自定义继承控件 ...
随机推荐
- 高能天气——团队Scrum冲刺阶段-Day 4
高能天气--团队Scrum冲刺阶段-Day 4 今日完成任务 于欣月:基本实现课程表功能:每一个设置课程表的地方设置一个EditText和一个TextView,根据我们学校的课程情况设置了25个Edi ...
- SpringMVC(九) RequestMapping请求参数
通过在控制器方法中使用@RequestParam(value="参数名",require=true/false,defaultvalue="")的方式,使在UR ...
- 「LOJ 556 Antileaf's Round」咱们去烧菜吧
「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...
- 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令
如何用dat批处理文件关闭某端口对应程序? 网上找到的大部分都是手动操作,第一步先查出端口,第二步在根据上一步查到的端口手动去关闭进程.但我的需求不是这样的,我需要全自动处理.用于 dubbo 服务进 ...
- Sublime Text下使用SFTP/FTP插件
一.前言 本文主要记录了Sublime Text编辑器下的SFTP/FTP的安装使用,方便linux和windows下的文件编辑,只是简单的记录,有不足之处,还望指教. 二.Linux和windows ...
- ORM for Net主流框架汇总与效率测试
框架已经被越来越多的人所关注与使用了,今天我们就来研究一下net方面的几个主流ORM框架,以及它们的效率测试(可能会有遗漏欢迎大家讨论). ORM框架:Object/Relation Mapping( ...
- Message Queue协议AMQP
历史: Message Queue的需求由来已久,80年代最早在金融交易中,高盛等公司采用Teknekron公司的产品,当时的Message queuing软件叫做:the information b ...
- 在eclipse中查看Android源码
声明:高手跳过此文章 当我们在eclipse中开发android程序的时候.往往须要看源码(可能是出于好奇,可能是读源码习惯),那么怎样查看Android源码呢? 比方以下这样的情况 图1 如果我们想 ...
- XML 高速入门总结
XML已经学习完了一段时间了.一直感觉知识比較琐碎,没有去好好总结.事实上越琐碎的知识也越须要我们去好好 理一下.将知识串起来.争取变得不再琐碎.以下是我学完xml画的一张图. 以下对XML进行一下简 ...
- Visual Studio 2012 调试程序加载缓慢,提示正在下载符号
当在Visual Studio 2012中调试程序的时候,整个过程加载缓慢,并且有类似"正在下载符号......"的提示. 这是因为Visual Studio在调试的时候,默认从M ...
