博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对View的onMeasure()方法的进一步研究
阅读量:6931 次
发布时间:2019-06-27

本文共 3304 字,大约阅读时间需要 11 分钟。

在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);    }}

布局文件为:

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;    }

  

 

  

  

转载于:https://www.cnblogs.com/ganchuanpu/p/6736440.html

你可能感兴趣的文章
一块GPU就能训练语义分割网络,百度PaddlePaddle是如何优化的?
查看>>
HBase 参考指南 3.0 翻译活动期待大家的参与 | ApacheCN
查看>>
canvas 拼图
查看>>
Golang 正则表达式(regexp)
查看>>
深入浅出谈Cookie
查看>>
命令行使用
查看>>
Java-001-面向对象
查看>>
日剧·日综资源集合(建议收藏)
查看>>
VuePress 静态网站生成
查看>>
辞职的新方式:一言不合就消失!
查看>>
Laravel 5.8 正式发布(文档翻译已启动)
查看>>
一篇Rust的30分钟介绍
查看>>
iOS应用代码注入防护
查看>>
Scrum框架和規則
查看>>
HBase写吞吐场景资源消耗量化分析及优化
查看>>
每天一本电子书 - Eloquent Javascript, 3rd Edition
查看>>
js基础进阶--promise和setTimeout执行顺序的问题
查看>>
element-ui+vue-cli3.0:el-upload
查看>>
leetcode讲解--771. Jewels and Stones
查看>>
MySQL实战 | 02-MySQL 如何恢复到半个月内任意一秒的状态?
查看>>