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的实现方法和流程. 主要介绍了自绘控件.自定义组合控件.自定义继承控件 ...
随机推荐
- python 实现远端ftp文件上传下载
python 实现ftp上传下载 * 脚本需要传入两个参数,参数1为需要从远端ftp站点下载文件名称,参数2为已知需要下载的文件md5值,文件下载完成后会自动进行md5值校验 * 运行示例 [root ...
- Java 获取并计算程序执行时间
一般输出日期时间经常会用到Date这个类: SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// ...
- rsync基础
参考资料:骏马金龙的rsync系列.该博主的博文质量很好,推荐大家关注. 环境 操作系统:CentOS Linux release 7.5.1804 (Core) 软件:rsync version ...
- C# 动态加载组件后怎么在开发环境中调试
动态加载组件 那就是简单的Assembly.Load动态加载dll而以.这网上资料也有不少.基本的思路基本上就是在本地上一个指定目录如[plugs]存在着一堆dll文件.主程序在初始运行时一般会把指定 ...
- java 注解 总结
http://www.importnew.com/23564.html 注解的好处: 1.能够读懂别人写的代码,特别是框架相关的代码. 2.本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以 ...
- 压缩归档文件审查工具p7zip-full
压缩归档文件审查工具p7zip-full 在数字取证中,会遇到各种形式的压缩文件和归档文件.为了处理这些不同的文件,Kali Linux提供了专用工具p7zip-full.该工具支持各种格式的压缩 ...
- 「PKUWC2018」猎人杀
「PKUWC2018」猎人杀 解题思路 首先有一个很妙的结论是问题可以转化为已经死掉的猎人继续算在概率里面,每一轮一直开枪直到射死一个之前没死的猎人为止. 证明,设所有猎人的概率之和为 \(W\) , ...
- 8.5 正睿暑期集训营 Day2
目录 2018.8.5 正睿暑期集训营 Day2 总结 A.占领地区(前缀和) B.配对(组合) C 导数卷积(NTT) 考试代码 T1 T2 T3 2018.8.5 正睿暑期集训营 Day2 时间: ...
- [JSOI2015]最小表示
题目大意:尽可能多地去掉一个有向无环图上的边,使得图的连通性不变. 思路:拓扑排序,然后倒序求出每个结点到出度为$0$的点的距离$d$,再倒序遍历每一个点$x$,以$d$为关键字对其出边降序排序,尝试 ...
- process information unavailable 的解决办法
有时候在centos上查看java进程时,会遇到process information unavailable 的情况,如下图: 不同账号之间kill进程时,可能会造成这种现象(比如:deploy用户 ...