自定义控件之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方法,这个方法是用来控制控件 ...
随机推荐
- spring boot 集成 mybatis,数据库为mysql
导入mven工程即可运行,方法不描述了,具体见 https://github.com/davidwang456/spring-boot-mybatis-demo
- java9新特性-15-全新的HTTP 客户端API
1.官方Feature 110: HTTP 2 Client 2.使用说明 HTTP,用于传输网页的协议,早在1997年就被采用在目前的1.1版本中.直到2015年,HTTP2才成为标准. H ...
- PostgreSQL Replication之第九章 与pgpool一起工作(2)
9.2 理解pgpool的功能 pgpool提供了如下功能: •连接池 •语句级别的复制 •负载均衡 •限制连接 •内存缓存 •并行查询 [当决定使用那些功能的时候,记住并非所有的功能可以在同一时间使 ...
- python import windows文件路经
import sys sys.path.append("E:\\python\\workspacepython\\PY001\\src\\testpy01") import str ...
- 栈 <stack> F - 宋飞正传
I’m out of stories. For years I’ve been writing stories, some rather silly, just to make simple prob ...
- nginx的Rewrite重写
location /{ if ($remote_addr=192.168.1.100){ //禁止此 ip 访问 ...
- HTML5的核心内容
开发者可以放心地使用html5的理由 兼容性.HTML5在老版本的浏览器可以正常运行,同时支持HTML5的新浏览器也能正常运行HTML4,用HTML4创建出来的网站不是必须全部重建的. 实用性.HTM ...
- ES6学习笔记(十六)async函数
1.含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是什么?一句话,它就是 Generator 函数的语法糖,号称异步的终极解决方案. 前文有一个 Gen ...
- NPashaP的二分图源码部分
源码链接:https://github.com/nelsonkuang/ant-admin/blob/master/src/utils/d3-viz.js 的二分图部分. 1.整体的级联结构 整个bp ...
- js cookie 页面倒计时
疯了啦 写了一篇没有保存需求:页面倒计时 只从第一次加购开始公共方法cookie的设置 获取function getCookie(c_name){ if (document.cookie.length ...