安卓之Custom View

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36347817/article/details/82113369

View工作流程

View工作流程主要指measure、layout、draw这三个流程,即测量、布局和绘制。

  measure确定View的自身的宽高

  layout确定View在父容器放置的位置

  draw将View绘制到屏幕上。

measure

为了更好理解measure过程,先了解MeasureSpec。

MeasureSpec代表一个32位int值,高2位代表SpecMode,低30位代表SpecSize。

SpecMode指的测量模式,SpecSize指在某种测量模式下规格大小。

SpecMode有三种:

  • EXACTLY

精确值模式,父容器已经检测出View所需要的精确大小,这时候View的最终大小就是SpecSize所指定的值。它对应代码LayoutParams(控件layout_width属性和layout_height属性)中match_parent和具体数值。

  • AT_MOST

最大值模式,父容器指定了一个可用大小值,只要不超过父容器允许最大尺寸即可。它对应代码LayoutParams(控件layout_width属性和layout_height属性)中wrap_content。

  • UNSPECIFIED

父容器不对View有任何限制,要多大给多大,如ListView。

自定义控件不重写onMeasure(),View类默认只支持EXACTLY模式,如果让View支持wrap_content属性,必须重写onMeasure()来指定wrap_content大小。代码如下:

private int mWidth = 500, mHeight = 450;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
    int finalWidth = mWidth > widthSpecSize ? mWidth : widthSpecSize;
    int finalheight = mHeight > heightSpecSize ? mHeight : heightSpecSize;
    //view支持wrap_content
    if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(finalWidth, finalheight);
    } else if (widthSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(finalWidth, heightSpecSize);
    } else if (heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(widthSpecSize, finalheight);
    }
}

setMeasuredDimension方法会设置View宽/高的测量值

layout

layout的作用是ViewGroup用来确定子元素的位置,当ViewGroup的位置被确定后,他在onLayout会遍历所有子元素并调用其layout方法。layout方法大致流程:首先通过setFrame设定View四个顶点位置,View四个顶点一旦确定,那么它在父容器中位置也就确定了。

draw

重写onDraw()方法,并在Canvas对象上绘制所需要的图形,简而言之,有画笔和画布就可:Android 画笔PaintAndroid 画布CanvasAndroid之画笔Paint和画布Canvas及实例练习圆角、刮刮卡、圆形头像、倒影效果

自定义attrs属性

attrs.xml

values目录下创建attrs.xml

<resources>
    <!--<declare-styleable>声明自定义属性-->
        <declare-styleable name="EmptyView">
        <!--<attr>声明具体自定义属性-->
        <attr name="empty_text" format="string"/>
        <attr name="empty_text_color" format="color"/>
        <attr name="empty_image" format="reference"/>
    </declare-styleable>
</resources>

这里format的color指的颜色。其他:reference指资源ID;dimension指尺寸;string、integer、boolean指基本数据类型。也可以用“|”来分隔不同的属性。

猜你喜欢

转载自blog.csdn.net/qq_36347817/article/details/82113369