在Android开发中,很多人对自定义View是望而生畏,但这又是向高级进阶的必经之路,主要是对View里面的很多方法不知道怎么理解,其中一个就是onMeasure()方法。

首先,我自定义一个MyView,继承于View,onMeasure()方法不做处理,直接调用super.onMeasure(widthMeasureSpec, heightMeasureSpec);

public class MyView extends View{
public MyView(Context context) {
super(context);
} public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
} public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} @TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

布局文件为:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <com.example.customviewdemo.View.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:padding="10dp"
android:background="#ff0000"/> </LinearLayout>

onMeasure()方法的作用就是测量View需要多大的空间,就是宽和高,在MyView中我没有做任何处理,使用View默认的测量规则,我们看下效果:

在android:layout_width和android:layout_height都为match_parent的时候,MyView填满全屏,当我们把android:layout_width和android:layout_height都为wrap_content的时候,我们看到MyView还是填满全屏,当我把android:layout_width和android:layout_height都这是为100dp的时候,我们看下效果

我们看到MyView的大小为100dp了。

结论:

1、View默认的测量规则是android:layout_width和android:layout_height为match_parent或者wrap_content时,是填充全屏的。

2、android:layout_width和android:layout_height设置为具体值时,那么是多少,宽高就是多少。

显然,默认的规则大部分不符合我们的需求,先来看下onMeasure()的参数,有两个参数,widthMeasureSpec,heightMeasureSpec,以前不明白,我以为是View本身的大小,仔细想想也不对,如果是本身的大小那还要你测什么啊,这两个参数是父布局给它提供的水平和垂直的空间要求,大家注意,只是父布局提供的要求,当然View也可以不遵守在View的android:layout_width和android:layout_height的值就是onMeasure()两个参数。什么意思,比如我为android:layout_width和android:layout_height设置的值为300dp,但是我在onMeasure()中,测量时不遵守这个300dp的空间要求,将onMeasure()的实现改为:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(100,100);
}

这样一样,不管android:layout_width和android:layout_height设置的值为多少,MyView显示的宽高都为100px,一般来说我们不这样做,我们要考虑父布局给出的宽高,即我们设置android:layout_width和android:layout_height的值。
结论:
onMeasure方法的作用就是计算出自定义View的宽度和高度。这个计算的过程参照父布局给出的大小,以及自己特点算出结果
一般来说使用如下的实现过程: 

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
} private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
//设置一个默认值,就是这个View的默认宽度为500,这个看我们自定义View的要求
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {//相当于我们设置为wrap_content
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {//相当于我们设置为match_parent或者为一个具体的值
result = specSize;
}
return result;
} private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
}
return result;
}

  

  

  

对View的onMeasure()方法的进一步研究的更多相关文章

  1. [转]Android View.onMeasure方法的理解

    转自:http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html Android View.onMeasure方法的理解 View在屏幕上显示出来要先经过 ...

  2. Android View.onMeasure方法的理解

    View在屏幕上显示出来要先经过measure(计算)和layout(布局).1.什么时候调用onMeasure方法? 当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,“你想要用多大地方 ...

  3. Android之View.onMeasure方法

    View在屏幕上显示出来要先经过measure(计算)和layout(布局). 1.什么时候调用onMeasure方法? 当控件的父元素正要放置该控件时调用.父元素会问子控件一个问题,“你想要用多大地 ...

  4. Android View.onMeasure方法的理解(转载)

    一下内容转载自http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html View在屏幕上显示出来要先经过measure(计算)和layout(布局).1 ...

  5. 【转载】深入剖析自定义View之onMeasure

    1.前言 自定义View中我们看到很多都重写了onMeasure方法,那么我们首先得知道onMeasure是做什么的.onMeasure中文意思就是测量,所以它是用于测量View的大小,影响View大 ...

  6. android自定义控件onMeasure方法

    1.自定义控件首先定义一个类继承View 有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/ ...

  7. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  8. Android中View的绘制过程 onMeasure方法简述 附有自定义View例子

    Android中View的绘制过程 onMeasure方法简述 附有自定义View例子 Android中View的绘制过程 当Activity获得焦点时,它将被要求绘制自己的布局,Android fr ...

  9. [转载]Android View.onMeasure方法的理解

    2013-12-18 10:56:28 转载自http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html View在屏幕上显示出来要先经过measure( ...

随机推荐

  1. scp 一次拷贝多个文件

    用正则表达式去匹配即可, scp  *.tar  root@11.11.11.12:/root/ 拷贝当前目录下的所有tar类型的文件到服务器上

  2. spring boot快速入门 8: 异常处理

    异常处理简单样例: 第一步:创建result实体类 package com.payease.domain; /** * http请求返回的最外层对象 * Created by liuxiaoming ...

  3. Error处理:/bin/bash^M: 坏的解释器: 没有该文件或目录(bad interpreter: No such file or directory)

    在Linux下编译运行脚本的时候出现”/bin/bash^M: 坏的解释器: 没有那个文件或目录(bad interpreter: No such file or directory)“这样的错误. ...

  4. js动画实现(一)

    requestAnimationFrame是什么? 在浏览器动画程序中,我们通常使用一个定时器来循环每隔几毫秒移动目标物体一次,来让它动起来.如今有一个好消息,浏览器开发商们决定:“嗨,为什么我们不在 ...

  5. 设计模式笔记-观察者(Observer)

    观察者设计模式应该是比较简单的一个设计模式. 定义 定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 简单理解就是: 当1个对象状态有所改变的时候,依 ...

  6. 决策树遇到sklearn.exceptions.NotFittedError: XXX instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.的解决方案

    1.异常信息: C:\Python36\python36.exe "E:/python_project/ImoocDataAnalysisMiningModeling/第6章 挖掘建模/6- ...

  7. C#实现文件下载的几种方式

    上篇博客也说了下C#中通过XML导出Excel,这些文件操作都挺有用的,下面是文件的下载,之前做项目都是把它写的空间日志中,以后有时间了把它们都弄出来 先把有问题的代码贴出来吧 using Syste ...

  8. Spring----有关bean的配置

    1.单例类的配置如果我们想创建一个单例类的bean,只能会通过静态工厂来创建.下图为一个单例类: Stage并没有提供公开的构造方法,构造方法都是私有的,必须通过getInstance()方法获得已经 ...

  9. git pull和git pull --rebase的使用

    使用下面的关系区别这两个操作: git pull = git fetch + git merge git pull --rebase = git fetch + git rebase 现在来看看git ...

  10. DIRECTORY_SEPARATOR 目录分隔符 php内置变量

    转自http://www.cnblogs.com/timelesszhuang/p/3814878.html 在windows我们习惯性的使用“\”作为文件分隔符,但是在linux上系统不认识这个标识 ...