自定义View

一、构造方法

1.一个参数 Context context,需要在代码中new出来

2.两个参数 Context context, AttributeSet attrs,在布局文件中添加该控件,对应的属性会存放在AttributeSet attrs中。

3.三个参数 Context context, AttributeSet attrs, int defStyleAttr,第三个参数是对应的自定义属性,三个参数的额构造函数不会被自动调用,需要在第二个构造函数中this调用,第三个参数设为0。

二、view的绘制流程

Measure->Layout->Draw

onMeasure(int,int)参数int型,32位,前2位mode,后30位size。

MeasureSpce的mode有三种:EXACTLY, AT_MOST,UNSPECIFIED。

EXACTLY:是明确了控件的大小,或者MATCH_PARENT,父布局(所在的ViewGroup)会将其设置为EXACTLY;

AT_MOST:子布局限制在一个最大之内,一般为WARP_CONTENT,父布局会将其设置为AT_MOST;

UNSPECIFIED:子布局想要多大给多大。

给控件设置了长和宽,onMeasure()测量的是设定的值;设置为WRAP_CONTENT,或者MATCH_PARENT,测量的结果就是MATCH_PARENT的长度,占满父布局。所以当设置为WRAP_CONTENT,需要重写,自己测量。

判断mode,不能直接使用size。

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);

    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int measuredHeight, measuredWidth;

    if (widthMode == MeasureSpec.EXACTLY) {
        measuredWidth = widthSize;
    } else {
        measuredWidth = SIZE;   //设置的定值
    }

    if (heightMode == MeasureSpec.EXACTLY) {
        measuredHeight = heightSize;
    } else {
        measuredHeight = SIZE;
    }

    setMeasuredDimension(measuredWidth, measuredHeight);
}

onLayout(),只有ViewGroup需要重写该方法,是为了给子控件布局的

三、自定义属性

1.values目录下创建attr.xml

declare-styleable name对应着相应的自定义view

attr:name为自定义属性名称,format为类型

方式1.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="NewView">
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="text" format="string" />
    </declare-styleable>
</resources>

方式2.

<attr name="firstColor" format="color" />  
<attr name="secondColor" format="color" />  
<attr name="circleWidth" format="dimension" />  
<attr name="speed" format="integer" />    
<declare-styleable name="CustomProgressBar">  
     <attr name="firstColor" />  
     <attr name="secondColor" />  
     <attr name="circleWidth" />  
     <attr name="speed" />  
</declare-styleable>  

2.在布局文件中使用属性

在布局最外层会自动生成命名空间 xmlns:app="http://schemas.android.com/apk/res-auto"

<com.wangpos.test.NewView
    app:text="AAAAAAAAA"
    app:textColor="@color/colorAccent"
    app:textSize="20px"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

3.在自定义view中的构造方法中获取自定义属性

获得属性:R.styleable.View名称_属性

TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.NewView);

    int textColor = a.getColor(R.styleable.NewView_textColor,0XFFFFFFFF);
    float textSize = a.getDimension(R.styleable.NewView_textSize, 36);
    String text = a.getString(R.styleable.NewView_text);

4.候选值属性,如match_parent,wrap_content

name为名字,value为对应的值

<attr name="position">
        <enum name="width" value="300" />
        <enum name="height" value="100" />
    </attr>

在布局中使用

app:position="height"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值