前言:

前面我们已经学过《Android 自定义 view(三)—— onDraw 方法理解》,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法

推荐文章:

http://blog.csdn.net/a396901990/article/details/36475213?utm_source=tuicool&utm_medium=referral

onMeasure 作用

(1)一般情况重写onMeasure()方法作用是为了自定义View尺寸的规则,如果你的自定义View的尺寸是根据父控件行为一致,就不需要重写onMeasure()方法
(2)如果不重写onMeasure方法,那么自定义view的尺寸默认就和父控件一样大小,当然也可以在布局文件里面写死宽高,而重写该方法可以根据自己的需求设置自定义view大小

认识 onMeasure

(0)onMeasure (int widthMeasureSpec, int heightMeasureSpec)是view自己的方法

(1)onMeasure 方法简单的理解就是是用于测量视图的大小,主要是用来测量自己和内容的来确定宽度和高度

(2)onMeasure有两个参数 ( int widthMeasureSpec, int heightMeasureSpec),该参数表示控件可获得的空间以及关于这个空间描述的元数据.

(3)widthMeasureSpec和heightMeasureSpec这两个值通常情况下都是由父视图经过计算后传递给子视图的,说明父视图会在一定程度上决定子视图的大小。

认识 MeasureSpec

在测量自定义view的大小之前,我们需要认识一个类MeasureSpec,它封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求  MeasureSpec由size和mode组成。

specMode一共有三种类型,如下所示:
1. EXACTLY
表示父视图希望子视图的大小应该是由specSize的值来决定的,系统默认会按照这个规则来设置子视图的大小,简单的说(当设置width或height为match_parent时,模式为EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的)
2. AT_MOST
表示子视图最多只能是specSize中指定的大小。(当设置为wrap_content时,模式为AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸)

3. UNSPECIFIED
表示开发人员可以将视图按照自己的意愿设置成任意的大小,没有任何限制。这种情况比较少见,不太会用到。

onMeasure 之我见示意图

 

onMeasure  实践练习

要去自定义控件上面写一段文字,根据宽度

/**
* Created by yishujun on 16/6/5.
*/
public class YView extends View {
    private Context mContext;
    //定义一个paint
    private Paint mPaint;

    private String mText = "测试文字,自定义view";
    //绘制时控制文本绘制的范围
    private Rect mBound;

    public YView(Context context) {
        this(context, null);
    }

    public YView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public YView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        mBound = new Rect();
        mPaint = new Paint();
        mPaint.setTextSize(60);
        mPaint.getTextBounds(mText, 0, mText.length(), mBound);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.GRAY);
        mPaint.setColor(Color.RED);
        canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);

    }

    /**
     * 比onDraw先执行
     * <p>
     * 一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。
     * 一个MeasureSpec由大小和模式组成
     * 它有三种模式:UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;
     * EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;
     * AT_MOST(至多),子元素至多达到指定大小的值。
     * <p>
     * 它常用的三个函数:
     * 1.static int getMode(int measureSpec):根据提供的测量值(格式)提取模式(上述三个模式之一)
     * 2.static int getSize(int measureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
     * 3.static int makeMeasureSpec(int size,int mode):根据提供的大小值和模式创建一个测量值(格式)
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int minimumWidth = getSuggestedMinimumWidth();
        final int minimumHeight = getSuggestedMinimumHeight();
        Log.e("YView", "---minimumWidth = " + minimumWidth + "");
        Log.e("YView", "---minimumHeight = " + minimumHeight + "");
        int width = measureWidth(minimumWidth, widthMeasureSpec);
        int height = measureHeight(minimumHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int measureWidth(int defaultWidth, int measureSpec) {

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.e("YViewWidth", "---speSize = " + specSize + "");

        switch (specMode) {
            case MeasureSpec.AT_MOST:
                defaultWidth = (int) mPaint.measureText(mText) + getPaddingLeft() + getPaddingRight();

                Log.e("YViewWidth", "---speMode = AT_MOST");
                break;
            case MeasureSpec.EXACTLY:
                Log.e("YViewWidth", "---speMode = EXACTLY");
                defaultWidth = specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                Log.e("YViewWidth", "---speMode = UNSPECIFIED");
                defaultWidth = Math.max(defaultWidth, specSize);
        }
        return defaultWidth;
    }

    private int measureHeight(int defaultHeight, int measureSpec) {

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        Log.e("YViewHeight", "---speSize = " + specSize + "");

        switch (specMode) {
            case MeasureSpec.AT_MOST:
                defaultHeight = (int) (-mPaint.ascent() + mPaint.descent()) + getPaddingTop() + getPaddingBottom();
                Log.e("YViewHeight", "---speMode = AT_MOST");
                break;
            case MeasureSpec.EXACTLY:
                defaultHeight = specSize;
                Log.e("YViewHeight", "---speSize = EXACTLY");
                break;
            case MeasureSpec.UNSPECIFIED:
                defaultHeight = Math.max(defaultHeight, specSize);
                Log.e("YViewHeight", "---speSize = UNSPECIFIED");
//        1.基准点是baseline
//        2.ascent:是baseline之上至字符最高处的距离
//        3.descent:是baseline之下至字符最低处的距离
//        4.leading:是上一行字符的descent到下一行的ascent之间的距离,也就是相邻行间的空白距离
//        5.top:是指的是最高字符到baseline的值,即ascent的最大值
//        6.bottom:是指最低字符到baseline的值,即descent的最大值

                break;
        }
        return defaultHeight;

    }
}

第一组:

 

第二组:

Android 自定义 view(四)—— onMeasure 方法理解的更多相关文章

  1. Android自定义View的实现方法,带你一步步深入了解View(四)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回 ...

  2. 【转】Android自定义View的实现方法,带你一步步深入了解View(四)

    原文网址: 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到 ...

  3. Android 自定义View 四个构造函数详解

    https://blog.csdn.net/zhao123h/article/details/52210732 在开发android开发过程中,很多人都会遇到自定义view,一般都需要继承自View类 ...

  4. Android 自定义View (四) 视频音量调控

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个下面的效果,我看下面一哥们说 ...

  5. android 自定义view 前的基础知识

    本篇文章是自己自学自定义view前的准备,具体参考资料来自 Android LayoutInflater原理分析,带你一步步深入了解View(一) Android视图绘制流程完全解析,带你一步步深入了 ...

  6. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  7. Android自定义View(三、深入解析控件测量onMeasure)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51490283 本文出自:[openXu的博客] 目录: onMeasure什么时候会被调用 ...

  8. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  9. 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍

    前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...

随机推荐

  1. Is It A Tree?[HDU1325][PKU1308]

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  2. BZOJ2087 : [Poi2010]Sheep

    一条边能连上当且仅当它没有经过任何点,并且两边的点都是偶数个. 枚举原点,通过极角排序求出哪些边是合法的,然后区间DP即可. 时间复杂度$O(nm\log m+n^3)$. #include<c ...

  3. H5开发中的问题总结

    最近公司做了一个出行日记的项目,里面的页面十多页,天天加班,做到吐血.总体来说,写页面的时候虽然是十多个页面,其实难度还是在每个页面的特效上.公司是易到用车,出行日记的页面在APP里有生成入口,有兴趣 ...

  4. 运用ASP.NET实现

    calation.cs using System; using System.Collections.Generic; using System.Linq; using System.Web; /// ...

  5. jqgrid cellEdit为true的时候,默认选中单元格值的解决方案

    jqgrid cellEdit为true的时候,点击单元格的时候,鼠标在单元格最前面闪. 这时候如果要修改数字内容,非常麻烦.要全选单元格内容,不然不好改. 点击单元格的时候,默认选中单元格值的解决方 ...

  6. Hive_数据倾斜处理

    Hive中三种join map join (小表join大表,将小表加入到内存) 设置map join: hive.auto.convert.join=true hive.mapjoin.smallt ...

  7. http协议笔记

    协议:双方/多方共同遵守的一个规范.类比生活中协议 理解: webservice=http协议+xml Rest         =http协议+json 开始,客户端和其他服务器都是没有关系的,比如 ...

  8. thinkPHP访问不同表前缀

    $Model=new Model(); $goods=$Model->Table('sdb_goods'); $param['brief']=array('like','%'.$p_title. ...

  9. 兼容IE浏览器的js浏览器全屏代码

    众所周知,IE是个奇葩的浏览器,但是由于用户量很大,开发者还是不得不为IE考虑一下,于是,各种浏览器相关的操作,都要多一个特别的判断——专门针对IE浏览器的判断,这里的全屏也不例外.看代码: func ...

  10. JQuery中on()函数详解

    JQuery API中定义的on方法,专业名词很多,读起来并不是那么容易,而对于开发人员知道函数怎么使用就可以了.本文将JQuery的说明翻译如下: on(events,[selector],[dat ...