前言:

  自定义控件的三大方法:

测量: onMeasure():  测量自己的大小,为正式布局提供建议
布局: onLayout(): 使用layout()函数对所有子控件布局
绘制: onDraw(): 根据布局的位置绘图

onDraw() 里面是绘制的操作,可以看下其他的文章,下面来了解 onMeasure()和onLayout()方法。

一、onMeasure()、测量

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

参数即父类传过来的两个宽高的"建议值",即把当前view的高设置为:heightMeasureSpec ;宽设置为:widthMeasureSpec

这个参数不是简单的整数类型,而是2位整数(模式类型)和30位整数(实际数值) 的组合

其中模式分为三种:

①、UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;UNSPECIFIED=00000000000000000000000000000000

②、EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;EXACTLY =01000000000000000000000000000000
③、AT_MOST(至多),子元素至多达到指定大小的值。 他们对应的二进制值分别是: AT_MOST =10000000000000000000000000000000 

最前面两位代表模式,分别对应十进制的0,1,2;

获取模式int值 和 获取数值int值的方法:

  1. int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
  2. int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
  3. int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
  4. int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);

模式的值有:

MeasureSpec.AT_MOST       = 2
MeasureSpec.EXACTLY = 1
MeasureSpec.UNSPECIFIED = 0

上面我们知道了 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法参数的意义

下面了解参数对应的三个模式分别对应的意义:

每一个模式都对应的xml布局中的一个值

wrap_content   --- MeasureSpec.AT_MOST
match_parent --- MeasureSpec.EXACTLY
具体值 --- MeasureSpec.UNSPECIFIED

注意:当模式是MeasureSpec.AT_MOST时,即wrap_content时,需要将大小设置一个数值。

二、onLayout() 、 布局

首先先了解几个需要用到的方法:

  (1)、

      这个方法和onMeasure()方法类似。其实这个方法的作用就是 设置当前View的宽高。

  (2)、

      这个方法就和方法类似了,不过少了第一个参数boolean changed

      这个方法的目的是用于当前ViewGroup中的子控件的布局

 

  再看方法,只要是继承ViewGroup的类都必须要重写该方法,来实现该控件内部子控件的布局情况。

  我们写一个自定义类继承ViewGroup实现Linearlayout垂直排列的效果看下:

  public class XViewGroup extends ViewGroup{
public XViewGroup(Context context) {
super(context);
}
public XViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public XViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
     
      
     // 计算所有子控件需要用到的宽高
int height = ; //记录根容器的高度
int width = ; //记录根容器的宽度
int count = getChildCount(); //记录容器内的子控件个数
for (int i=;i<count;i++) {
//测量子控件
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//获得子控件的高度和宽度
int childHeight = child.getMeasuredHeight();
int childWidth = child.getMeasuredWidth();
//得到最大宽度,并且累加高度
height += childHeight;
width = Math.max(childWidth, width);
}
     // 设置当前View的宽高
setMeasuredDimension((measureWidthMode == MeasureSpec.EXACTLY) ? measureWidth: width, (measureHeightMode == MeasureSpec.EXACTLY) ? measureHeight: height);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int top = ;
int count = getChildCount();
for (int i=;i<count;i++) {
View child = getChildAt(i);
int childHeight = child.getMeasuredHeight();
int childWidth = child.getMeasuredWidth();
//该子控件在父容器的位置 , 高度是之前所有子控件的高度和开始 ,从上往下排列,就实现了类似Linearlayout布局垂直排列的布局
child.layout(0, top, childWidth, top + childHeight); //以父容器左上角为原点进行布局
top += childHeight;
}
} }

自定义控件详解(五):onMeasure()、onLayout()的更多相关文章

  1. 《Android群英传》读书笔记 (2) 第三章 控件架构与自定义控件详解 + 第四章 ListView使用技巧 + 第五章 Scroll分析

    第三章 Android控件架构与自定义控件详解 1.Android控件架构下图是UI界面架构图,每个Activity都有一个Window对象,通常是由PhoneWindow类来实现的.PhoneWin ...

  2. .NET DLL 保护措施详解(五)常规条件下的破解

    为了证实在常规手段破解下能有效保护程序核心功能(演示版本对AES加解密算法及数据库的密钥(一段字符串)进行了保护),特对此DLL保护思路进行相应的测试,包含了反编译及反射测试,看是否能得到AES加解密 ...

  3. 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。

    原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...

  4. python设计模式之迭代器与生成器详解(五)

    前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...

  5. WindowsPhone自定义控件详解(二) - 模板类库分析

    转自:http://blog.csdn.net/mr_raptor/article/details/7251948 WindowsPhone自定义控件详解(一) - 控件类库分析 上一节主要分析了控件 ...

  6. pika详解(五)登录认证及connectionParameters

    pika详解(五)登录认证及connectionParameters 本文链接:https://blog.csdn.net/comprel/article/details/94662916 版权 pi ...

  7. 第十五节,卷积神经网络之AlexNet网络详解(五)

    原文 ImageNet Classification with Deep ConvolutionalNeural Networks 下载地址:http://papers.nips.cc/paper/4 ...

  8. View绘制详解(五),draw方法细节详解之View的滚动/滑动问题

    关于View绘制系列的文章已经完成了四篇了,前面四篇文章主要带小伙伴们熟悉一下View的体系的整体框架.View的测量以及布局等过程,从本篇博客开始,我们就来看看View的绘制过程.View的绘制涉及 ...

  9. Mac下Intellij IDea发布Java Web项目详解五 开始测试

    测试前准备工作目录 Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intell ...

  10. OkHttp3源码详解(五) okhttp连接池复用机制

    1.概述 提高网络性能优化,很重要的一点就是降低延迟和提升响应速度. 通常我们在浏览器中发起请求的时候header部分往往是这样的 keep-alive 就是浏览器和服务端之间保持长连接,这个连接是可 ...

随机推荐

  1. Javascript百学不厌 - 模块模式

    记录自己觉得重要又可能忘记的东西 用模块模式产生安全的对象: var serial_maker = function () { var preifx = ''; var seq = 0; return ...

  2. 机器学习基石笔记:12 Nonlinear Transformation

    一.二次假设 实际上线性假设的模型复杂度是受到限制的, 需要高次假设打破这个限制. 假设数据不是线性可分的,但是可以被一个圆心在原点的圆分开, 需要我们重新设计基于该圆的PLA等算法吗? 不用, 只需 ...

  3. Linux学习笔记之二————Linux系统的文件和目录

    一.Windows和Linux文件系统区别 1.在 windows 平台下,打开“计算机”,我们看到的是一个个的驱动器盘符: 每个驱动器都有自己的根目录结构,这样形成了多个树并列的情形,如图所示:  ...

  4. 边缘化搭建 DotNet Core 2.1 自动化构建和部署环境(上)

    写在前面 写这篇文章的缘由是由于笔者的对新兴技术方向有所追求,但个人资产有限,只能容许购买一台阿里云低配1核2G服务器.服务器上搭建了 Centos7 & Docker & Jenki ...

  5. Spring Cloud Gateway入门

    1.什么是Spring Cloud GatewaySpring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技 ...

  6. iOS开发(1):设置APP的图标与启动图 | iOS图标的尺寸 | LaunchScreen的使用

    每个APP都应该有自己的图标跟启动图. 这里介绍怎么设置iOS的APP的图标跟启动图. (1)图标 小程的xcode是10.0版本,设置图标的入口如下: 点击入口后,进到设置页面,如下: 可以看到有很 ...

  7. Ubuntu Docker版本的更新与安装

    突然发现自己的docker版本特别的低,目前是1.9.1属于古董级别的了,想更新一下最新版本,这样最新的一下命令就可以被支持.研究了半天都没有更新成功,更新后的版本始终都是1.9.1 :查阅了官网资料 ...

  8. 教你控制 RecyclerView 滑动的节奏

    最近,PM升级改版落地页,其中有一个很奇怪的交互需求,需求是这样的: 用户在该页面可以上下无限滑动,但是,在上拉滑动过程中,当内容切换为另一个内容的时候,新的内容先吸顶,然后停止滑动,让用户知道他已经 ...

  9. tensorflow实现循环神经网络

    包括卷积神经网络(CNN)在内的各种前馈神经网络模型, 其一次前馈过程的输出只与当前输入有关与历史输入无关. 递归神经网络(Recurrent Neural Network, RNN)充分挖掘了序列数 ...

  10. [转]来扯点ionic3[2] 页面一线牵 珍惜这段缘

    本文转自:https://www.jianshu.com/p/de40aeb3d371 往期传送门 来扯点ionic3[0] 吹完牛再入门也不迟 来扯点ionic3[1] 创建一个新页面     上一 ...