Android自定义View总结
Android自定义View总结
步骤
- 自定义View的属性
- 在View的构造方法获取我们自定义的属性值
- 重写onMesure()方法
- 重写onDraw()方法
自定义View的属性
在res/values/下建立attrs.xml,定义控件的属性和样式,如下所示:
<declare-styleable name="CircleImageView">
<attr name="border_width" format="dimension" />
<attr name="border_color" format="color" />
</declare-styleable>
format为取值类型,有以下类型:
- string 字符串
- color 颜色值,如#ffffff
- dimension 尺寸,xml中设置为dp/dip, 字体为sp
- integer 数值 1
- enum 枚举类型
- reference 引用,如@drawable/ic_launcher
- float 浮点类型 如1.0
- boolean 布尔类型 true或false
- fraction 百分数 如100%
- flag 位或运算
在xml布局文件中,声明我们的自定义View,示例代码:
<com.infzm.o2o.view.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/iv_head_icon"
android:layout_width="wrap_content"
android:layout_height="59dp"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:src="@drawable/ic_profile_user_default"
app:border_color="@color/white"
app:border_width="2dp" >
注意需要引入命名空间,xmlns:app=”http://schemas.android.com/apk/res-auto",不然无法使用我们的属性
在View的构造方法获取我们自定义的属性值
重写3个构造方法,示例代码如下:
1
|
public CircleImageView(Context context) {
|
重写onMesure()方法
这个方法用来计算View的大小,如果需要计算View的大小,则需要重写此方法。
示例代码:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
...
if (widthMode == MeasureSpec.EXACTLY) {
// Parent has told us how big to be. So be it.
width = widthSize;
} else {
if (mLayout != null && mEllipsize == null) {
des = desired(mLayout);
}
...
setMeasuredDimension(width, height);
}
这里有几个点需要提一下是specMode,我们视图的规格模式,有三种类型:
- MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的,一般是设置了明确的值或者说是MATCH_PARENT。
- MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,不建议子视图大小超过specSize中给定的值,一般为WRAP_CONTENT。
- MeasureSpec.UNSPECIFIED:可以随意指定视图的大小。
最终我们会调用setMesuredDimension(width, height);来设置最终视图的大小,width和height就是我们计算得来的值。
重写onDraw()方法
我们通过这个方法来绘制我们的视图,示例代码:
@Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
}
}
比如示例代码中,我们通过画布来绘制一个圆形。
最后附上开源控件,自定义圆形头像的解析:
1 |
