• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android视图学习---从源码角度来理解onMeasure过程

android视图学习---从源码角度来理解onMeasure过程

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android视图学习---从源码角度来理解onMeasure过程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android视图学习---从源码角度来理解onMeasure过程


前面的几篇文章写的都非常好的,非常的了不起,介绍的非常的详细

view的绘制:onMeasure onLayout onDraw 执行流程 【这里其实就是RootViewImpl 里面setView之后的一个流程】

这里是ViewRoot的子类,也叫实现类里面的ViewRootImpl

android怎么把view添加到窗口的:这里面进一步让我们知道整个视图的组成是有window,phoneWindow,decorview【这里面从setContentView,到addView 其实就走到setView】

这里是ViewRoot里面的

surface分析:这里面更深一步的让我们知道了activity是怎么获得一块显存,然后把视图画出来的,ViewRoot在这一步如何跟系统服务交互的,也就是怎么拿到显存的,

ViewRoot是整个显示系统中最为关键的东西,看起来这个东西好像和View有那么点关系,其实它根本和View等UI关系不大,它不过是一个Handler罢了,唯一有关系的就是它其中有一个变量为Surface类型

正是ViewRoot是一个handle类的派生,就让activityTread和System Service 进程服务搞起来了,

 

接下来的内容又回到view的绘制过程里面,再一次看看onMeasure详细的绘制流程,

 

从源码步骤来看:

1.setView()函数里面:

有行代码 requestLayout(),只是执行的第一部,

2.在requestLayout()里面:

执行了调度遍历 scheduleTraversals();

3.在调度遍历函数scheduleTraversals里面:

发送了一个空的handle消息

4.在handleMessage里面:

调用 执行遍历函数 performTraversals();到了这一步,也就是基本到了文章1里面说的绘制流程了,但是我们只是分析下onMeasure的详细过程

5.在performTraversals函数里面:这个函数太长了,

如果是初次调用:host.dispatchAttachToWindow() 这个函数的作用就是把视图与window窗口关联起来,

这里面详细有三个函数:onAttachToWindow();参数信息

listener.onViewAttachToWindow();回调

onWindowVisibilityChanged()

host.fitSystemWindow():这一步计算视图跟window之间的padding

而且这里面要非常的注意,执行了requestLayout()方法,一层一层的调用父视图

最后一步就是拿到window的宽和高

如果不是初次调用:直接拿到window的宽和高 供后面的Measure 测量用的

6.在measure里面:

有两个参数,宽和高,这个是父亲传递给孩子的规格,而这个规格的测量是调用getRootMeasure(window的期望孩子的宽高,LayoutParams的宽高)

7.onMeasure()函数:

这个韩式在measure里面调用的,只有你要求我重新绘制,或者高度和宽度变了,我才重新绘制 调用SetMeasureDimension()

8.SetMeasureDimension():这个函数非常的重要,但是里面的代码非常的简单,也是我们重载需要写的,它决定了测量之后获得的宽高

9.getDefaultSize :返回一个默认值,这个默认值调用了 makMesaureSpec 这个函数也非常的简单,size+mode,是二进制的加法

 

整个过程就结束了,这就是整个onMeasure的详细过程,当然这里面还涉及到非常的详细知识。

 

下面的文章是参考:

 

一、Measure本质


小福:我今天分享是的measure架构设计相关的,先问一个问题,measure的本质是什么?
小黑:这个我知道,是Android系统创建UI界面的measure、layout、draw三步骤的第一步,主要用于测量视图大小,更详细点说是把“相对值”(WRAP_CONTENT, FILL_PARENT, MATCH_PARENT)转换为具体指的过程。


小福:小黑说的对,再问一个问题,视图大小指的是什么?
小白:视图大小是在视图在屏幕上显示的大小,也就是开发的时候通过layout_width与layout_heigh设置的?
小福:小白说的只是其中一个作为开发人员的角度。Android系统设计中Canvas是无穷大的,假如一个屏幕的大小是320 * 480 ,但是layout_width="480px", layout_heigh="800px",很明显视图的宽高大于实际屏幕大小。 问题来了,视图的大小到底是屏幕上显示的大小,还是视图的实际大小(即使是超过了屏幕大小)?
小黑:具体视图显示大小是由开发人员设置,之后由我控件开发工程师在onMeasure中决定,如果向小福说的尺寸,即使超过屏幕我可以决定是width=320, heigh = 480 还是widt= 480, heigh = 800 ,决定权在我这里,一会在我分享的时候会写一个Demo来演示。 (视图根据绘制大小不同分类:内容型视图、图形型视图)


小白:Canvas是什么?小福:这个在之后分享draw过程的时候在详细讨论,可以笼统的理解为画画时使用的画布。
小福:Measure的本质是把视图布局时使用的相对值转换为具体值的过程。
 

二、Measure代码流程


小福:先从源码看下measure执行流程,看看这些过程中都做了些什么。以下都是android.view.ViewRootImpl.java类中的源码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

public final class ViewRootImpl extends Handler implements ViewParent,

View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {

 

// 1 所有子视图的requestLayout方法,最总都会触发根视图此方法

public void requestLayout() {

checkThread();

// 需要重新布局

mLayoutRequested = true;

 

scheduleTraversals();

}

 

// 调度遍历

public void scheduleTraversals() {

if (!mTraversalScheduled) {

mTraversalScheduled = true;

 

.....

 

// 当前类继承自Handler,发出一个空消息,目的是加入Message队列

sendEmptyMessage(DO_TRAVERSAL);

}

}

 

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

 

...

 

case DO_TRAVERSAL:

...

// 处理DO_TRAVERSAL消息

performTraversals();

...

break;

 

.....

}

}

 

// 执行遍历

private void performTraversals() {

 

final View host = mView;

 

int desiredWindowWidth;

int desiredWindowHeight;

int childWidthMeasureSpec;

int childHeightMeasureSpec;

......

 

if (mLayoutRequested && !mStopped) {

......

childWidthMeasureSpec = getRoot

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-26零停重启程序工具Huptime研究
  • 2017-05-26Android中使用findViewByMe提升组件查找效率,光伏组件转换效率
  • 2017-05-26我的android学习经历11,android学习经历11
  • 2017-05-224.3.1 BroadcastReceiver牛刀小试
  • 2017-05-26Android 手机卫士11--窗体弹出PopupWindow,11--popupwindow
  • 2017-05-26仿QQ空间根据位置弹出PopupWindow显示更多操作效果,popupwindow
  • 2017-05-26android 浅谈Aidl 通讯机制,androidaidl
  • 2017-05-26arcgis andriod 加载影像,arcgisandriod
  • 2017-05-26Android端 配置极光推送
  • 2017-05-26切换网站主域名经验总结

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 老人桌面===花花绿绿的桌面,老人桌面
    • FragmentStatePagerAdapter和FragmentPagerAdapter区别,fragmentpageradapter
    • Android Volley框架的使用,androidvolley框架
    • android adb pull push,androidadb
    • Android中AIDL详解
    • 我的android学习经历5,android学习经历5
    • Android 上千实例源码分析以及开源分析
    • 硅谷新闻4--解决页签手指按下从左到右滑动的bug,硅谷4--
    • Picasso处理同一url,但资源变了的情况,picassourl
    • Android百度地图API集成三《搜索》,android《搜索》

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有