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的实现方法和流程. 主要介绍了自绘控件.自定义组合控件.自定义继承控件 ...
随机推荐
- Java动态性之反射机制(reflection)
说到反射机制,第一次接触的人可能会比较懵,反射?什么反射?怎么反射?反射是干嘛的?下面我将在这篇文章中讲讲Java的反射机制 不过在这之前,还有一个问题需要解决,标题名中的动态性,说起动态性,我先介绍 ...
- SpringBoot详细研究-04部署测试与监控
这部分的内容实际就是devops的主要工作内容,当然一名合格的程序要也需要掌握这部分的知识. 热部署 简单来说,在开发时,修改了任何的代码,IDE将自动编译运行及发布:在发布时,当前发布不影响线上服务 ...
- 使用 Maven 来管理项目 & 从 0 开始搭建 Maven 项目
maven 是 apache 的一个开源软件,纯 Java 编写的,专门用于管理 Java 项目的一个工具. maven 就是一个工具而已,用不用都不耽误你刷刷的敲代码,那为什么我们还要学习它呢? 那 ...
- 3,EasyNetQ-发布/订阅
一.发布 在发布/订阅模式中的角色是彼此陌生的. 一个发布者只是向世界说这个已经发生了,一位订阅者告诉世界“我在乎这个”. 在这个模型中,没有人关心特定的事件是很好的. 消息可能有一个订阅者,可能有2 ...
- ZJOI2019day1退役记
ZJOI2019day1退役记 每天都在划水,考场上心态炸了,也没什么好说的. 有人催我更退役记,等成绩出来了再更更吧,成绩出来也没心情更了,落差好大,还打不过文化课选手 虽然被卡常数卡到心态爆炸,但 ...
- [ZOJ3781]Paint the Grid Reloaded
思路: 先用DFS缩点,然后BFS找出每个点出发能到达的最长路,取$min$. 注意多组数据,初始化一定要仔细,刚开始存边的$e$忘记初始化,一直WA,调了半个晚上. 一开始和网上的题解对拍$T=1$ ...
- KVM源代码解读:linux-3.17.4\include\linux\kvm_host.h
#ifndef __KVM_HOST_H #define __KVM_HOST_H /* * This work is licensed under the terms of the GNU GPL, ...
- hdu 5735 Born Slippy 暴力
Born Slippy 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5735 Description Professor Zhang has a r ...
- spring cloud 学习(5) - config server
分布式环境下的统一配置框架,已经有不少了,比如百度的disconf,阿里的diamand.今天来看下spring cloud对应的解决方案: 如上图,从架构上就可以看出与disconf之类的有很大不同 ...
- IAR EWARM 字体设置
如果只想简单的设置,可进行如下设置 Tools->IDE Options->Editor->Colors and Fonts->Editor Font->Font 但是这 ...
