zoukankan      html  css  js  c++  java
  • Android开发之View重写相关API-onLayout,onMeasure,MeasureSpec

     1.onLayout

    android.view.ViewGroup

    protected void onLayout(boolean changed, int l, int t, int r, int b)

    执行layout操作时调用onLayout方法。View要给它的每个Child设定size和position。拥有Children的子类需要重写onLayout方法并且调用每个Child的layout方法。

    参数changed表示view的size或position发生变化。参数l, t, r, b分别表示相对于parent的left, top, right, bottom position。

     2.onMeasure

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

    测量View及其Content,确定measuredWidth和measuredHeight。在方法measure(int, int)中调用。重写onMeasure方法时,需要调用方法setMeasuredDimension(int, int),存储View的measuredWidth和measuredHeight。若存储失败,方法measure(int, int)会抛出异常IllegalStateException。可以调用super.onMeasure(int, int)方法。

    除非MeasureSpec准许更大的size,否则measure的默认实现是background size。子类重写onMeasure(int, int)提供Content的更佳测量。如果onMeasure被重写,子类必须保证measuredWidth和measuredHeight至少是view的minHeight和minWidth。minHeight/Width通过getSuggestedMinimumHight/Width()获取。

    参数width/heightMeasureSpec表示parent强加的horizontal/vertical space要求。

    void android.view.ViewGroup.layout(int l, int t, int r, int b)

    给view及其descendants设定size和position。它正是layout机制的第2个步,每个parent调用它的chlidren的layout操作。使用在measure阶段测量得到的size和position数据完成layout操作。拥有child的子类必须重写onLayout方法,调用每个child的layout操作。

    void android.view.ViewGroup.measureChildren(int widthMeasureSpec, int heightMeasureSpec)

    请View的所有children测量themseles, 测量依据是View的MeasureSpec和padding。忽略处于GONE状态的children,是否GONE状态由getChildMeasureSpec来确定。

    参数width/heightMeasureSpec表示view的width/height要求。

    3.MeasureSpec

    android.view.View.MeasureSpec

    MeasureSpec是View的内部类

    public static class MeasureSpec

    MeasureSpec封装从parent传递给child的layout要求。每个MeasureSpec表示对width/height的要求。MeasureSpec由size和mode组成。可用的mode有3种:

    1. UNSPECIFIED表示parent没有强加给child任何constraint。

    2. EXACTLY表示parent已经确定child的精确size。

    3. AT_MOST表示child可以设定为specified size之内的任何值。

    MeasureSpec实现为int类型,相比object类型,降低了allocation。可以将<size, mode>元组pack和unpack为int类型。

    MeasureSpec定义的常量有:

    private static final int MODE_SHIFT = 30;

    private static final int MODE_MASK  = 0x3 << MODE_SHIFT;

    public static final int UNSPECIFIED = 0 << MODE_SHIFT;

    public static final int EXACTLY     = 1 << MODE_SHIFT;

    public static final int AT_MOST     = 2 << MODE_SHIFT;

    MeasureSpec定义的方法有:

    public static String toString(int measureSpec) { 
        int mode = getMode(measureSpec); 
        int size = getSize(measureSpec);

        StringBuilder sb = new StringBuilder("MeasureSpec: ");

        if (mode == UNSPECIFIED) 
            sb.append("UNSPECIFIED "); 
        else if (mode == EXACTLY) 
            sb.append("EXACTLY "); 
        else if (mode == AT_MOST) 
            sb.append("AT_MOST "); 
        else 
            sb.append(mode).append(" ");

        sb.append(size); 
        return sb.toString(); 
    }

    public static int getSize(int measureSpec) { 
        return (measureSpec & ~MODE_MASK); 
    }

    public static int getMode(int measureSpec) { 
        return (measureSpec & MODE_MASK); 
    }

    public static int makeMeasureSpec(int size, int mode) { 
        return size + mode; 
    }

  • 相关阅读:
    oracle grant授权的理解
    SQL SERVER 2005 版本以上 CTE递归查询的实现
    常用的加密解密技术之——【加密原理】
    常用的汇编指令
    常用加密解密技术之——【DES算法实现过程分析】
    VC6.0编译器中混有.c文件时出现fatal error C1853错误解决办法
    C++ Primer读书笔记
    Shot(数学+物理题,不简单)
    [置顶] C++/C 数据类型的取值范围
    <fzu1922>非主流
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/3822582.html
Copyright © 2011-2022 走看看