1、自定义控件首先定义一个类继承View

有时,Android系统控件无法满足我们的需求,因此有必要自定义View。具体方法参见官方开发文档:http://developer.android.com/guide/topics/ui/custom-components.html

一般来说,自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小。

protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

onMeasure传入的两个参数是由上一层控件传入的大小,有多种情况,重写该方法时需要对计算控件的实际大小,然后调用setMeasuredDimension(int, int)设置实际大小。

onMeasure传入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸数值,而是将模式和尺寸组合在一起的数值。我们需要通过int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。

mode共有三种情况,取值分别为MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。

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方法传入的模式。

我们来看下程序的代码:

xml布局文件:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:id="@+id/activity_main"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:paddingBottom="@dimen/activity_vertical_margin"
  8. android:paddingLeft="@dimen/activity_horizontal_margin"
  9. android:paddingRight="@dimen/activity_horizontal_margin"
  10. android:paddingTop="@dimen/activity_vertical_margin"
  11. tools:context="im.weiyuan.com.zidingyikongjian.MainActivity">
  12.  
  13. <im.weiyuan.com.zidingyikongjian.MesureView
  14. android:layout_width="100px"
  15. android:layout_height="200px" />
  16. </RelativeLayout>

我们来看看类的代码,该代码继承自View类

  1. package im.weiyuan.com.zidingyikongjian;
  2.  
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.util.Log;
  6. import android.view.View;
  7.  
  8. /**
  9. * Created by wei.yuan on 2017/6/2.
  10. */
  11.  
  12. public class MesureView extends View {
  13. /**
  14. *
  15. * new MesureView(context)的时候调用该构造函数
  16. * */
  17. public MesureView(Context context) {
  18. super(context);
  19. }
  20.  
  21. /**
  22. * 在布局中引用
  23. *
  24. * */
  25.  
  26. public MesureView(Context context, AttributeSet attrs) {
  27. super(context, attrs);
  28. }
  29. /**
  30. * 在布局中引用
  31. *
  32. * */
  33. public MesureView(Context context, AttributeSet attrs, int defStyleAttr) {
  34. super(context, attrs, defStyleAttr);
  35. }
  36. /**
  37. * 在布局中引用
  38. *
  39. * */
  40.  
  41. public MesureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  42. super(context, attrs, defStyleAttr, defStyleRes);
  43. }
  44.  
  45. /**
  46. *
  47. *
  48. * */
  49. @Override
  50. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  51. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  52. // 第一步提取出具体对象的测量模式和大小
  53. int size = MeasureSpec.getSize(widthMeasureSpec);
  54. int mode = MeasureSpec.getMode(widthMeasureSpec);
  55. Log.d("123456",size+"");
  56. if(mode == MeasureSpec.EXACTLY){ //默认就是精确的模式
  57. Log.d("123456",mode+"");
  58. }
  59.  
  60. }
  61. }

我们来看看日志打印的效果:

  1. MeasureSpec.getSize获得对应的控件的大小:单位是px,这里上面测量的是控件的宽度,在xml布局里面设置的是100px,这里打印就是100px
    这里控件在xml指定的是具体的100px大小值,这里获得的mode就是精确的模式、
    setMeasuredDimension这个方法,这个方法决定了当前View的大小
    现在我们在xml中指定了控件的宽度是100px,高度是100px
    现在我们要通过代码指定控件的宽度和高度可以使用函数
  1. setMeasuredDimension
    现在我们的首先的像素是1080*1920,我们想要这个控件填充我们的整个屏幕可以设置下面的代码:
  1. package im.weiyuan.com.zidingyikongjian;
  2.  
  3. import android.content.Context;
  4. import android.util.AttributeSet;
  5. import android.util.Log;
  6. import android.view.View;
  7.  
  8. /**
  9. * Created by wei.yuan on 2017/6/2.
  10. */
  11.  
  12. public class MesureView extends View {
  13. /**
  14. *
  15. * new MesureView(context)的时候调用该构造函数
  16. * */
  17. public MesureView(Context context) {
  18. super(context);
  19. }
  20.  
  21. /**
  22. * 在布局中引用
  23. *
  24. * */
  25.  
  26. public MesureView(Context context, AttributeSet attrs) {
  27. super(context, attrs);
  28. }
  29. /**
  30. * 在布局中引用
  31. *
  32. * */
  33. public MesureView(Context context, AttributeSet attrs, int defStyleAttr) {
  34. super(context, attrs, defStyleAttr);
  35. }
  36. /**
  37. * 在布局中引用
  38. *
  39. * */
  40.  
  41. public MesureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  42. super(context, attrs, defStyleAttr, defStyleRes);
  43. }
  44.  
  45. /**
  46. *
  47. *
  48. * */
  49. @Override
  50. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  51. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  52. // 第一步提取出具体对象的测量模式和大小
  53. int size = MeasureSpec.getSize(widthMeasureSpec);
  54. int mode = MeasureSpec.getMode(widthMeasureSpec);
  55. Log.d("123456",size+"");
  56. if(mode == MeasureSpec.EXACTLY){ //默认就是精确的模式
  57. Log.d("123456",mode+"");
  58. }
  59.  
  60. //设置控制的大小
  61. setMeasuredDimension(1080,1920);//单位是像素
  62.  
  63. }
  64. }

android自定义控件onMeasure方法的更多相关文章

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

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

  2. android自定义控件 onMeasure() 测量尺寸

    上次讲的自定义控件刷新点屏幕的任意地方都会刷新,而且在xml里自定义控件下面放一个textview的话,这个TextView是显示不出来的,不只这个,以前的几个自定义控件都是 为什么呢?今天来讲下on ...

  3. Android的onMeasure方法

    在Android开发中,当Android原生控件不能满足我们的需求的时候,就需要自定义View.View在屏幕上绘制出来先要经过measure(计算)和layout(布局). 什么时候调用onMeas ...

  4. Android View.onMeasure方法的理解

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

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

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

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

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

  7. android自定义控件onLayout方法

    onLayout设置子控件的位置,对应一些普通的控件例如Button.TextView等控件,不存在子控件,所以可以不用复写该方法. 向线性布局.相对布局等存在子控件,可以覆写该方法去控制子控件的位置 ...

  8. android自定义控件(6)-详解在onMeasure()方法中如何测量一个控件尺寸

    今天的任务就是详细研究一下protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法.如果只是说要重写什么方法有什么 ...

  9. Android 自定义控件高度设置onMeasure方法

    最近使用hellocharts需要表格横向显示,而activity需要竖屏显示,在旋转以后,默认宽度为不超过屏幕宽度,则一直无法显示全控件. 此时需要修改onMeasure方法,这个方法是用来控制控件 ...

随机推荐

  1. nginx 配置重定向及nginx配置if

    需求:地址 http://testa/inlinePreview/live.html?id=463738305721405440重定向到 http://testb/shares/live.html?n ...

  2. 01 . Prometheus简介及安装配置Grafana

    Promethus简介 Prometheus受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Brog系统演变而来),从2012年开始由前Google工程师在S ...

  3. 07 . Nginx常用模块及案例

    访问控制 用户访问控制 ngx_http_auth_basic_module 有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问 ...

  4. Java实现 LeetCode 468 验证IP地址

    468. 验证IP地址 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址. IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(&qu ...

  5. Java实现 LeetCode 154 寻找旋转排序数组中的最小值 II(二)

    154. 寻找旋转排序数组中的最小值 II 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找 ...

  6. java中eclipse控制台接受输入的方法

    如果是超大字符串的话,相比较来说用io流比较快捷 import java.io.BufferedReader; import java.io.IOException; import java.io.I ...

  7. Java实现台阶问题

    1 问题描述 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级,求总共有多少种跳法. 2 解决方案 2.1 递归法 如果整个台阶只有1级,则显然只有一种跳法.如果台阶有2级,则有两种跳法:一种是分 ...

  8. Python——day3

    看到右边的时钟了吗?  我想世界最公平的一件事就是每个人的每一小时.每一天.每一年都是相同的,每个人的时间都是一样的. 一直保持温热感是一件很了不起的事,加油,屏幕前的你和我. 明天,还在等你 回顾d ...

  9. awardRotate转盘插件文字模糊问题和图片加载问题

    前言 最近在做一个转盘抽奖页面,使用了awardRotate.js发现字体和图片都有模糊,绘制的时候图片绘制不全,搜索一下之后发现针对awardRotate的解决方法比较少,针对canvas的比较多, ...

  10. MySQL死锁及解决方案

    一.MySQL锁类型 1. MySQL常用存储引擎的锁机制 MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-level locking)或表 ...