最近一直在接触自定义控件的知识,自己就尝试着写了一个小的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
    }@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint 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);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {// TODO Auto-generated method stubLog.e("123", "change===" + changed + " left===" + left + " top==="+ top + " right===" + right + " bottom===" + bottom);super.onLayout(changed, left, top, right, bottom);}@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubLog.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.DrawViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="#ff0000" /></RelativeLayout>

先看下我们的打印结果

  1 09-28 22:53:26.901: E/123(17442): drawview_22 09-28 22:53:26.959: E/123(17442): MeasureSpec.UNSPECIFIED==03 09-28 22:53:26.959: E/123(17442): MeasureSpec.AT_MOST==-21474836484 09-28 22:53:26.959: E/123(17442): MeasureSpec.EXACTLY==10737418245 09-28 22:53:26.959: E/123(17442): widthMeasureSpec===10737419746 09-28 22:53:26.960: E/123(17442): heightMeasureSpec===-21474829587 09-28 22:53:26.960: E/123(17442): widthMode==1073741824 widthSize===1508 09-28 22:53:26.960: E/123(17442): heightMode==-2147483648 heightSize===6909 09-28 22:53:26.960: E/123(17442): MeasureSpec.UNSPECIFIED==010 09-28 22:53:26.960: E/123(17442): MeasureSpec.AT_MOST==-214748364811 09-28 22:53:26.961: E/123(17442): MeasureSpec.EXACTLY==107374182412 09-28 22:53:26.961: E/123(17442): widthMeasureSpec===107374189913 09-28 22:53:26.961: E/123(17442): heightMeasureSpec===107374197414 09-28 22:53:26.961: E/123(17442): widthMode==1073741824 widthSize===7515 09-28 22:53:26.961: E/123(17442): heightMode==1073741824 heightSize===15016 09-28 22:53:27.001: E/123(17442): change===true left===0 top===0 right===75 bottom===7517 09-28 22:53:27.030: E/123(17442): MeasureSpec.UNSPECIFIED==018 09-28 22:53:27.031: E/123(17442): MeasureSpec.AT_MOST==-214748364819 09-28 22:53:27.031: E/123(17442): MeasureSpec.EXACTLY==107374182420 09-28 22:53:27.031: E/123(17442): widthMeasureSpec===107374197421 09-28 22:53:27.031: E/123(17442): heightMeasureSpec===-214748295822 09-28 22:53:27.031: E/123(17442): widthMode==1073741824 widthSize===15023 09-28 22:53:27.031: E/123(17442): heightMode==-2147483648 heightSize===69024 09-28 22:53:27.031: E/123(17442): MeasureSpec.UNSPECIFIED==025 09-28 22:53:27.031: E/123(17442): MeasureSpec.AT_MOST==-214748364826 09-28 22:53:27.031: E/123(17442): MeasureSpec.EXACTLY==107374182427 09-28 22:53:27.032: E/123(17442): widthMeasureSpec===107374189928 09-28 22:53:27.032: E/123(17442): heightMeasureSpec===107374197429 09-28 22:53:27.032: E/123(17442): widthMode==1073741824 widthSize===7530 09-28 22:53:27.032: E/123(17442): heightMode==1073741824 heightSize===15031 09-28 22:53:27.033: E/123(17442): change===false left===0 top===0 right===75 bottom===7532 09-28 22:53:27.045: E/123(17442): 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方法传入的模式。

转载于:https://www.cnblogs.com/zhangshuli-1989/p/vz_custom_15910151.html

自定义控件之onMeasure相关推荐

  1. Android自定义控件之onMeasure详解

    在Android开发中往往需要根据需求对原生控件进行自定义,其中主要涉及到的就是onMeasure,onLayout和onDraw三个方法的重写与使用,其中onMeasure是其中最复杂的一个方法,很 ...

  2. Android开发笔记(一百五十三)OpenGL绘制三维图形的流程

    从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨如何在Android中进行OpenGL开发. OpenGL的全称是"Open Graphics Library", ...

  3. Android 面试题 android中级---初级---知识点

    // Android 的中等知识理解 1 自定义控件 2 在android中跨进程之间通讯有那几种 ? 3 RecyclerView 了解情况 4 Android Fragment和Fragment之 ...

  4. Android仿美团切换城市

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/49757731 最近一直关注一些比较有名的app,像美团.58.赶集网.淘宝等等.主要目的就是 ...

  5. 易到用车面试总结(android)

    问到 基础知识 1. 适配器模式在 安卓中的应用. 2. Service 的启动方式. 3. 广播的注册方式有几种? 有什么不同? 4.public  private protected 以及缺省的作 ...

  6. Android开发中的一些小知识点记录(101-120)

    编写不易,如有转载,请声明出处:http://blog.csdn.net/zxc514257857/article/details/118554522 Android开发中的一些小知识点记录(1-20 ...

  7. android绘制过程3d图形,Android开发之OpenGL绘制三维图形的流程

    从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨如何在Android中进行OpenGL开发. OpenGL的全称是"Open Graphics Library", ...

  8. recycleView使用之2 :横向现实图片之图片是正方形

    今天大神要求,recycleView的横向显示三张图片需要显示的是正方形的,因为前边已经贴出代码关于recyview的正常使用. 解决问题的猜想1 : 在现实的图片条目上想方法:将图片本身的宽高做成适 ...

  9. Android UI 之一步步教你自定义控件(自定义属性、合理设计onMeasure、合理设计onDraw等)

    Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高.     一个相对完善的自定义控件在布局文件中和java代码中都 ...

最新文章

  1. juc java_深入理解JUC(java.util.concurrent)
  2. JDBC——入门知识【转】
  3. eclipse安装m2e.sourcelookup插件debug第三方源码(spring)
  4. VTK:可视化之VectorText
  5. Angular的scope. apply和CRM WebClient UI的modify方法
  6. java 删除txt,如何从.txt文件中删除2个值
  7. SUN服务器清除所有报错信息,SUN服务器可能遇到的问题总结.doc
  8. 将本地文件上传到gitlab上
  9. python正则表达式怎么表示零个或多个字符_VBA中正则表达式之分组
  10. html js修改readonly,js控制html元素的readonly属性
  11. Android File存储
  12. Linux中的Ext2、ext3、ext4文件系统如何对磁盘中的文件进行存储和管理
  13. oneno浏览器插件_Send to OneNote 1.2.13
  14. 水晶报表Crystal Reports实例
  15. excel中如何解锁锁定单元格
  16. 初中数学抽象教学的案例_初中数学教学案例与反思
  17. Android跳转应用市场更新自己《完美适配大部分手机应用商店》
  18. SPARC架构下的反汇编(一)——SPARC简介
  19. python收益风险点图_AAVE当前风险与收益是否有偏差?如何评估DeFi投资组合?
  20. Python:百分制转五分制

热门文章

  1. 结合MongoDB开发LBS应用
  2. An Implementation of Double-Array Trie
  3. ubuntu 14.04 安装 cuda 6.5
  4. 动态查看JVM内存的工具
  5. 一些数据结构的思想(3)
  6. Node.js 极简入门Helloworld版服务器例子
  7. SGU101 求有重边的无向图欧拉迹
  8. Ninja Blocks物联网平台简介
  9. c++中的输入输出方法
  10. 【NetApp】FC盘不能和装有ATA盘的DS14盘柜接入同一个loop中。