ViewGroup之onMeasure方法和onLayout方法

ViewGroup的绘图流程:ViewGroup绘制包括两个步骤:1.measure 2.layout
  在两个步骤中分别调用回调函数:1.onMeasure()   2.onLayout()
  1.onMeasure() 在这个函数中,ViewGroup会接受childView的请求的大小,然后通过childView的 measure(newWidthMeasureSpec, heightMeasureSpec)函数存储到childView中,以便childView的getMeasuredWidth() andgetMeasuredHeight() 的值可以被后续工作得到。
  2.onLayout() 在这个函数中,ViewGroup会拿到childView的getMeasuredWidth() andgetMeasuredHeight(),用来布局所有的childView。
  3.View.MeasureSpec 与 LayoutParams 这两个类,是ViewGroup与childView协商大小用的。其中,View.MeasureSpec是ViewGroup用来部署 childView用的, LayoutParams是childView告诉ViewGroup 我需要多大的地方。
  4.在View 的onMeasure的最后要调用setMeasuredDimension()这个方法存储View的大小,这个方法决定了当前View的大小。

        具体详见Android官方文档 dev guide->User Interface->How Android Draws Views
二 View,ViewGroup的手势监听顺序与使用
     View的手势监听相关回调函数:onTouchEvent()
     ViewGroup的手势监听相关回调函数:onTouchEvent(),onInterceptTouchEvent()
     1.这两个回调函数都会返回一个boolean变量,表示是否消费了此手势。如果消费了,返回true,如果未消费,返回false。
     2.当用户触摸一下屏幕,产生手势MotionEvent,
ViewGroup的onInterceptTouchEvent()会接受此MotionEvent。如果此回调函数返回true,则表示此ViewGroup消费了此手势,不想再让他的childView去处理,childView的 onTouchEvent()便不会再接受此手势,同时此ViewGroup的onTouchEvent()会接受此手势。 如果此回调函数返回false,则表示此ViewGroup未消费了此手势,想让他的childView去处理,childView的  onTouchEvent()接受此手势,同时此ViewGroup的onTouchEvent()不会接受此手势。

在继承ViewGroup类时,需要重写两个方法,分别是onMeasure和onLayout。

1,在方法onMeasure中调用setMeasuredDimension方法

void android.view.View.setMeasuredDimension(int measuredWidth,
int measuredHeight)

在onMeasure(int, int)中,必须调用setMeasuredDimension(int width, int height)来存储测量得到的宽度和高度值,如果没有这么去做会触发异常IllegalStateException。

2,在方法onMeasure中调用孩子的measure方法

void android.view.View.measure(int widthMeasureSpec, int heightMeasureSpec)

这个方法用来测量出view的大小。父view使用width参数和height参数来提供constraint信息。实际上,view的测量工作在onMeasure(int, int)方法中完成。因此,只有onMeasure(int, int)方法可以且必须被重写。参数widthMeasureSpec提供view的水平空间的规格说明,参数heightMeasureSpec提供view的垂直空间的规格说明。

3,解析onMeasure(int, int)方法

void android.view.View.onMeasure(int widthMeasureSpec,
int heightMeasureSpec)

测量view及其内容来确定view的宽度和高度。这个方法在measure(int, int)中被调用,必须被重写来精确和有效的测量view的内容。

在重写这个方法时,必须调用setMeasuredDimension(int, int)来存储测量得到的宽度和高度值。执行失败会触发一个IllegalStateException异常。调用父view的onMeasure(int, int)是合法有效的用法。

view的基本测量数据默认取其背景尺寸,除非允许更大的尺寸。子view必须重写onMeasure(int, int)来提供其内容更加准确的测量数值。如果被重写,子类确保测量的height和width至少是view的最小高度和宽度(通过getSuggestedMinimumHeight()和getSuggestedMinimumWidth()获取)。

4,解析onLayout(boolean, int, int, int, int)方法

void android.view.ViewGroup.onLayout(boolean changed, int l, int t, int r, int b)

调用场景:在view给其孩子设置尺寸和位置时被调用。子view,包括孩子在内,必须重写onLayout(boolean, int, int, int, int)方法,并且调用各自的layout(int,
int, int, int)方法。

参数说明:参数changed表示view有新的尺寸或位置;参数l表示相对于父view的Left位置;参数t表示相对于父view的Top位置;参数r表示相对于父view的Right位置;参数b表示相对于父view的Bottom位置。.

5,解析View.MeasureSpec类

android.view.View.MeasureSpec

MeasureSpec对象,封装了layout规格说明,并且从父view传递给子view。每个MeasureSpec对象代表了width或height的规格。

MeasureSpec对象包含一个size和一个mode,其中mode可以取以下三个数值之一:

  • UNSPECIFIED,1073741824 [0x40000000],未加规定的,表示没有给子view添加任何规定。
  • EXACTLY,0 [0x0],精确的,表示父view为子view确定精确的尺寸。
  • AT_MOST,-2147483648 [0x80000000],子view可以在指定的尺寸内尽量大。
时间: 2024-08-03 02:47:25

ViewGroup之onMeasure方法和onLayout方法的相关文章

Javascript数组的排序:sort()方法和reverse()方法

文章简介: JavaScript中的数组排序. JavaScript提供了sort()方法和reverse()方法,使得我们可以简单的对数组进行排序操作和逆序操作.其中: 1.JavaScript的sort()中如果没有指定比较函数,则默认会按照字符的编码顺序进行升序排序.也就是说如果我们想要对数值进行排序得到的不一定是我们想要的结果. 2.Javascript的reverse()将数组中的元素逆序. 先看看上面的第一点,如果有一个数组arr=[1,6,3,7,9],使用arr.sort()后,

ThinkPHP 中M方法和D方法的具体区别

M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类.   使用M方法 如果是如下情况,请考虑使用 M方法:   对数据表进行简单的 CURD 操作而无复杂的业务逻辑时 只有个别的表有较为复杂的业务逻辑时,将 M方法 与实例化 CommonModel 类进行结合使用 M方法 甚至可以简单看着就是对参数表名对应的数据表的操作:   $User = M('User');  使用D方法 如果是如下

JQuery中attr方法和removeAttr方法用法实例

  本文实例讲述了JQuery中attr方法和removeAttr方法用法.分享给大家供大家参考.具体如下: ? 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 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:

JQuery中attr方法和removeAttr方法用法实例_jquery

本文实例讲述了JQuery中attr方法和removeAttr方法用法.分享给大家供大家参考.具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"

想写一个IIS扩展模块,如何在上下文中获得HTTP请求实体,POST方法和GET方法分别怎样获取?

问题描述 想写一个IIS扩展模块,如何在上下文中获得HTTP请求实体,POST方法和GET方法分别怎样获取? 具体点就是在IHttpContext还是IHttpRequest中用什么方法啊

安卓意图-android中的intent对象的addCategory方法和setType方法有什么用区别

问题描述 android中的intent对象的addCategory方法和setType方法有什么用区别 android中的intent对象的addCategory方法和setType方法有什么用区别 按照语翻译的中文字面意思很相似啊, 解决方案 这个一两句说不清楚,你去看看资料,网上很多解释,主要是自己动手用用,别总看

重写equals方法和hashcode方法的作用

 重写equals方法和hashcode方法的作用 作用:区分同一个类的不同对象是否是同一个对象. 应用:在Hibernate 定义 Model实体类的 联合主键的时候用到. 举例说明: 1.数据库中的表teacher表,包括三个字段,id.name.level.其中id和name作为联合主键. 2.类在类的角度,如果想定义一个联合主键,使用多个属性作为实体类的关键字,那么方式为定义一个单独的类,里面包含多个属性,并且将这个类包含在原有类中. public class Teacher{     

java方法-java中decodeStream方法和openStream方法有什么区别和联系

问题描述 java中decodeStream方法和openStream方法有什么区别和联系 java中decodeStream方法和openStream方法有什么区别和联系 URL方法的参数是有哪几个参数组成的 解决方案 http://www.cnblogs.com/yourancao520/archive/2012/06/25/2561367.htmlhttp://blog.sina.com.cn/s/blog_588508f801010dh6.html

java线程中 start方法和run方法的区别和联系是什么

问题描述 java线程中 start方法和run方法的区别和联系是什么 java线程中 start方法和run方法的区别和联系是什么 start是启动一个线程到就绪状态 run是运行一个线程 要run一个线程必须先start一个线程,这么理解对不 解决方案 通过start启动线程,内部调用run,如果你直接调用run,就是同步的,会阻塞 解决方案二: run方法里写的是每个线程需要执行的代码 run 只是调用你自己写的run方法而已.根线程调用无关. start才是启动线程的方法 解决方案三: