自定义控件之onMeasure
最近一直在接触自定义控件的知识,自己就尝试着写了一个小的demo,算是对自定义知识点进行下总结
今天先来看下自定义控件需要重写的三个重要方法
看代码
package com.example.testcode; import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View; public class DrawView extends View { public DrawView(Context context) {
super(context);
Log.e("123", "drawview_1");
// TODO Auto-generated constructor stub
} public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.e("123", "drawview_3");
// TODO Auto-generated constructor stub
} public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.e("123", "drawview_2");
// TODO Auto-generated constructor stub
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
Log.e("123", "MeasureSpec.UNSPECIFIED==" + MeasureSpec.UNSPECIFIED);
Log.e("123", "MeasureSpec.AT_MOST==" + MeasureSpec.AT_MOST);
Log.e("123", "MeasureSpec.EXACTLY==" + MeasureSpec.EXACTLY);
Log.e("123", "widthMeasureSpec===" + widthMeasureSpec);
Log.e("123", "heightMeasureSpec===" + heightMeasureSpec);
Log.e("123", "widthMode==" + widthMode + " widthSize===" + widthSize);
Log.e("123", "heightMode==" + heightMode + " heightSize==="
+ heightSize);
//这两个方法必须有一个,否则会报错
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(75, 75);
} @Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
Log.e("123", "change===" + changed + " left===" + left + " top==="
+ top + " right===" + right + " bottom===" + bottom);
super.onLayout(changed, left, top, right, bottom);
} @Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
Log.e("123", "onDraw");
super.onDraw(canvas);
}
}
xml中使用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.testcode.MainActivity" > <com.example.testcode.DrawView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#ff0000" /> </RelativeLayout>
先看下我们的打印结果
- ::26.901: E/(): drawview_2
- ::26.959: E/(): MeasureSpec.UNSPECIFIED==
- ::26.959: E/(): MeasureSpec.AT_MOST==-
- ::26.959: E/(): MeasureSpec.EXACTLY==
- ::26.959: E/(): widthMeasureSpec===
- ::26.960: E/(): heightMeasureSpec===-
- ::26.960: E/(): widthMode== widthSize===
- ::26.960: E/(): heightMode==- heightSize===
- ::26.960: E/(): MeasureSpec.UNSPECIFIED==
- ::26.960: E/(): MeasureSpec.AT_MOST==-
- ::26.961: E/(): MeasureSpec.EXACTLY==
- ::26.961: E/(): widthMeasureSpec===
- ::26.961: E/(): heightMeasureSpec===
- ::26.961: E/(): widthMode== widthSize===
- ::26.961: E/(): heightMode== heightSize===
- ::27.001: E/(): change===true left=== top=== right=== bottom===
- ::27.030: E/(): MeasureSpec.UNSPECIFIED==
- ::27.031: E/(): MeasureSpec.AT_MOST==-
- ::27.031: E/(): MeasureSpec.EXACTLY==
- ::27.031: E/(): widthMeasureSpec===
- ::27.031: E/(): heightMeasureSpec===-
- ::27.031: E/(): widthMode== widthSize===
- ::27.031: E/(): heightMode==- heightSize===
- ::27.031: E/(): MeasureSpec.UNSPECIFIED==
- ::27.031: E/(): MeasureSpec.AT_MOST==-
- ::27.031: E/(): MeasureSpec.EXACTLY==
- ::27.032: E/(): widthMeasureSpec===
- ::27.032: E/(): heightMeasureSpec===
- ::27.032: E/(): widthMode== widthSize===
- ::27.032: E/(): heightMode== heightSize===
- ::27.033: E/(): change===false left=== top=== right=== bottom===
- ::27.045: E/(): onDraw
从上面的结果我们可以知道xml中控件加载过程
1.xml中使用的控件,加载的时候,调用的是控件两个参数的方法
public DrawView(Context context, AttributeSet attrs) {
}
一个是上下文,一个是属性
2.解析来会调用
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
}
方法,这个方法是用来确定控件的宽高的,这个值是从控件的width、height中读出来的。但是我们发现,这两个值的打印结果很奇怪,甚至还有负数。网上对此的解释是
onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。
具体什么我也不清楚,不过,它其实是包含了很多信息在里面的。一个就是,从这个数值,我们可以获得这个控件宽跟高的形式
使用如下方法
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
这个mode的取值,可以有一下三种
MeasureSpec.EXACTLY-是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width="50dip",或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。
MeasureSpec.AT_MOST 是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行 变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。
MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。
自定义控件之onMeasure的更多相关文章
- Android View的绘制过程
首先是view的绘制过程~最主要的分三部分 measure layout draw 看字面意思,计算,布局,画~ android中控件相当于是画在一个无限大的画布上的,那就产生了几个问题 画布无限大, ...
- 【Android 界面效果15】Android UI 之一步步教你自定义控件(自定义属性、合理设计onMeasure、合理设计onDraw等)
Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高. 一个相对完善的自定义控件在布局文件中和java ...
- Android UI 之一步步教你自定义控件(自定义属性、合理设计onMeasure、合理设计onDraw等)
Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高. 一个相对完善的自定义控件在布局文件中和java ...
- android自定义控件 onMeasure() 测量尺寸
上次讲的自定义控件刷新点屏幕的任意地方都会刷新,而且在xml里自定义控件下面放一个textview的话,这个TextView是显示不出来的,不只这个,以前的几个自定义控件都是 为什么呢?今天来讲下on ...
- 自定义控件详解(五):onMeasure()、onLayout()
前言: 自定义控件的三大方法: 测量: onMeasure(): 测量自己的大小,为正式布局提供建议 布局: onLayout(): 使用layout()函数对所有子控件布局 绘制: onDraw() ...
- android自定义控件onMeasure方法
1.自定义控件首先定义一个类继承View 有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/ ...
- android自定义控件(8)-利用onMeasure测量使图片拉伸永不变形,解决屏幕适配问题
使用ImageView会遇到的问题 在Android应用中,都少不了图片的显示,ImageView,轮播图,ViewPager等等,很多都是来显示图片的,很多时候,我们都希望图片能够在宽度上填充父窗体 ...
- android自定义控件(6)-详解在onMeasure()方法中如何测量一个控件尺寸
今天的任务就是详细研究一下protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法.如果只是说要重写什么方法有什么 ...
- Android 自定义控件高度设置onMeasure方法
最近使用hellocharts需要表格横向显示,而activity需要竖屏显示,在旋转以后,默认宽度为不超过屏幕宽度,则一直无法显示全控件. 此时需要修改onMeasure方法,这个方法是用来控制控件 ...
随机推荐
- 减少XML文件数
在android开发中,做出漂亮的ui的应用,往往有数量庞大的xml文件.比如,我们要给一个Button加上一个selector,如果背景不是图片,就得写三个xml文件,分别是:edit_focuse ...
- springMVC学习笔记_转载(一)-----springMVC原理
阅读目录 一.什么是springmvc 二.mvc在b/s系统下的应用 三.SpringMVC框架介绍 回到顶部 一.什么是springmvc springMVC是spring框架的一个模块,spri ...
- 初学者指南:ZFS 是什么,为什么要使用 ZFS?
作者: John Paul 译者: LCTT Lv Feng 今天,我们来谈论一下 ZFS,一个先进的文件系统.我们将讨论 ZFS 从何而来,它是什么,以及为什么它在科技界和企业界如此受欢迎. 虽然我 ...
- Java ——代理模式[转发]
1. 简介 代理模式(Proxy Pattern)是GoF 23种Java常用设计模式之一.代理模式的定义:Provide a surrogate or placeholder for anothe ...
- python之禅---对象与元类
众所周知,python是一门面向对象的编程语言,python中一切皆对象,那么我们先探讨一下什么是对象. 一.对象 在生活中一个事物就是一个对象,比如:一只猫就是一个对象,猫的体型.猫毛的颜色等是它的 ...
- 雅礼集训1-9day爆零记
雅礼集训1-9day爆零记 先膜一下虐爆我的JEFF巨佬 Day0 我也不知道我要去干嘛,就不想搞文化科 (文化太辣鸡了.jpg) 听李总说可以去看(羡慕)各路大佬谈笑风声,我就报一个名吧,没想到还真 ...
- linux基础入门(二)命令
原创作品,允许转载,转载时请务必声明作者信息和本声明. https://www.cnblogs.com/zhu520/p/10732334.html =[本人小白,有错指出.谢谢! 一:使用Secur ...
- 【Uva 11400】Lighting System Design
[Link]: [Description] 你要构建一个供电系统; 给你n种灯泡来构建这么一个系统; 每种灯泡有4个参数 1.灯泡的工作电压 2.灯泡的所需的电源的花费(只要买一个电源就能供这种灯泡的 ...
- Maven学习总结(21)——Maven常用的几个核心概念
在使用Maven的过程中,经常会遇到几个核心的概念,准确的理解这些概念将会有莫大的帮助. 1. POM(Project Object Model)项目对象模型 POM 与 Java 代码实现了解耦,当 ...
- ArcGIS Engine获得要素的中心点坐标
IPoint centerPoint =new PointClass();//获得要素的中心点 IArea pArea = pFeature.Shape as IArea; pArea.QueryCe ...