一、View源码分析

ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程全是通过ViewRoot来完成的。

在ActivityThread中,当Activity对象被创建后,会将DectorView添加到Window中,同时会创建ViewRootImpl对象,并将

ViewRootImpl对象和decorView建立关联,这个过程我们可以参看源码:

root = new ViewRootImpl(view.getContext(),display);
root.setView(view,wparams,panelparentView);

View的绘制流程是从ViewRoot的performTeaversals方法开始的,它经过measure、layout、draw三个过程才能最终将一个View绘制出来。

其中measure用来测量View的宽和高,layout用来确定View在父容器中放置的位置,而draw负责将View绘制在屏幕上。

针对performTraversals的大致流程:

如图所示,performTraversals会依次调用performMeasure、performLayout和performDraw三个方法,分别完成顶级View的measure、layout和draw三大流程。

PperformMeasure会调用measure方法,measure方法又会调用onMeasure,其中onMeasure又会调用所有子元素的measure方法完成测量。

同理,performLayout和performDraw也是如此。

DecorView是顶级View,它其实是一个FrameLayout,View层的事件都先经过DecorView,然后才传递给我们的View。

1.1、Measure的原理

measure过程中,如果是View,则通过measure方法即可完成测量过程,如果是ViewGroup,则需要完成自己的测量过程外,

还会遍历去调用所有子元素的measure方法,各个子元素再递归去执行这个流程。

1、View的measure过程

View的measure过程由其measure方法完成,measure方法是被final修饰的方法,不能重写。在View的measure方法中会去调用View的onMeasure方法,

因此只需要看onMeasure方法的实现即可:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

setMeasureDimension方法会设置View的宽和高来代表测量的结束,因此我们只需要看getDefaultSize方法即可:

public static int getDefaultSize(int size, int measureSpec) {int result = size;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:result = size;break;case MeasureSpec.AT_MOST:case MeasureSpec.EXACTLY:result = specSize;break;}return result;
}

对于我们来说只需要看AT_MOST和EXACTLY两种情况,其实getDefaultSize返回的大小就是measureSpec中的specSize,它就是View测量后的大小。

而UNSPECIFIED这种情况一般用于系统内部的测量过程,在这种情况下,View的大小为getDefault的第一个参数size,即宽和高分别是

getSuggestedMinimumWidth和getSuggestedMinimumHeught这两个方法的返回值。

protected int getSuggestedMinimumHeight() {return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());
}
protected int getSuggestedMinimumWidth() {return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}

可以看出,如果在没有指定背景的情况下,宽度和高度分别是mMinWidth和mMinHeight,如果不指定该属性,则默认为0.

如果指定背景的情况下,宽度和高度分别是max(mMinHeight, mBackground.getMinimumHeight())和max(mMinWidth, mBackground.getMinimumWidth())

那么我来看看mBackground.getMinimumWidth()方法:

public int getMinimumWidth() {final int intrinsicWidth = getIntrinsicWidth();return intrinsicWidth > 0 ? intrinsicWidth : 0;
}

可以看出,在Drawable有原始宽度的情况下,该方法返回的就是Drawable的原始宽度,当然高度也是如此。

转载于:https://www.cnblogs.com/pengjingya/p/5510714.html

39、自定义控件(四)-- View源码分析相关推荐

  1. android view 源码分析,Android ViewPager源码详细分析

    1.问题 由于Android Framework源码很庞大,所以读源码必须带着问题来读!没有问题,创造问题再来读!否则很容易迷失在无数的方法与属性之中,最后无功而返. 那么,关于ViewPager有什 ...

  2. axios核心内容(四)源码分析

    axios之源码分析 1.源码目录结构 2.源码分析 (1)axios与Axios的关系 (2)instance与axios的区别 (3)axios运行的整体流程 (4)axios的请求/响应拦截器 ...

  3. AbstractBeanDefinition:lenientConstructorResolution属性源码分析

    版本:spring-framework-4.1 一概述 在看AbstractBeanDefinition源码时,注意到lenientConstructorResolution属性有诸多不疑,现在通过示 ...

  4. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  5. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  6. (4.2.40)阿里开源路由框架ARouter的源码分析

    一需求背景 1 Android原生方案的不足 2 自定义路由框架的适用场景 3 对自定义路由框架的设想 二ARouter的概述 三ARouter的引入和使用 四源码分析 1 arouter-annot ...

  7. Android MultiDex 源码分析

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.启用 MultiDex Android 5.0 和之后的版本 Android 5.0 之前的版本 二.MultiD ...

  8. Spring源码分析(三)

    Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...

  9. 使用U盘传数据时操作系统做了什么(源码分析)

    一.背景 学习linux文件系统时考虑一个具体的问题:我们经常会用U盘传输东西到计算机中.当我们把U盘插入到一台计算机上,并且从U盘中复制文件到计算机里,然后卸载U盘,将U盘拔出.操作系统在这一连串过 ...

最新文章

  1. 【经验】如何查看gcc、g++不加-std时的默认版本
  2. 加密选项_视频会议Zoom 5.0版本重大更新,增强加密功能提供更多安全选项
  3. C++(20)--类型自动转换
  4. ORA-01552 :非系统表空间 'xxxx'不能使用系统回退段
  5. mysql中字符串处理替换字符replace和连接字符串函数concat
  6. 【对讲机的那点事】维修对讲机你会拆卸电路板上的集成电路块吗?
  7. NLP学习01--BP神经网络
  8. P-Called-Party-ID 头域的应用说明
  9. phpstorm 设置注释
  10. java11下载_Java11 64位下载_Java SE Development Kit 11(JDK11)下载 11.0.0 官方版_当载软件站...
  11. 使用elastic job 不分片任务加载失败的可能原因
  12. 学计算机要学工图吗,工程图学及计算机绘图: 非机类
  13. 线性代数 第二章 矩阵 知识点总结(Jeff自我感悟)
  14. 计算机语言底层用汉语拼音设计,设计英语元素计算机汉字输入拼音代码的研究...
  15. 威廉玛丽大学计算机本科专业,威廉玛丽学院本科专业有哪些?
  16. ContOs的网络配置
  17. 可视化利器Tensorboard
  18. 搭建Genero BDL环境-安装篇
  19. R语言 关联规则(二)
  20. 【Java】使用Jconsole连接远程云服务器(基于华为云Centos7)

热门文章

  1. eclipse中hibernate和mybatis中xml配置文件的没有标签提醒解决方法
  2. MapReduce原理及其主要实现平台分析
  3. rhel6.5网卡初始化错误解决
  4. 【openSUSE】软件源和软件搜索
  5. 逻辑备库之ORA-01403解决方法
  6. java中 构造器与void
  7. 更新增加一个门店ID字段的值
  8. 谜题 (Puzzle,ACM/ICPC World Finals 1993,UVa227)
  9. 【模板】并查集 两种路径压缩写法(类模板和函数模板)
  10. os.environ详解