1. 简介
前面分析了一大堆原理:
自定义View原理篇(1)- measure过程
自定义View原理篇(2)- layout过程
自定义View原理篇(3)- draw过程
现在来看看是如何实现自定义View:
2.自定义View的分类
自定义View
可以分为两大类,一种是自定义单一View
,另一种是自定义ViewGroup
。具体如下图所示:
类型 | 实现 | 目的 |
---|---|---|
自定义单一View | 继承系统已有View 如:TextView |
扩展已有View的功能 |
继承View | 实现一些不规则效果 | |
自定义ViewGroup | 继承系统已有ViewGroup 如:LinearLayout |
扩展已有ViewGroup的功能 组合View功能 |
继承ViewGroup | 实现自定义布局 |
本章主要介绍一下自定义单一View
,自定义ViewGroup
下一章来说明。
3.自定义单一View
自定义单一View
又分为两类,一类是继承系统已有View
,另一类是直接继承View
类,我们分开来看下。
3.1 继承系统已有View
这种方式可以去扩展系统已有View
的功能,比如要显示一个圆形的ImageView
等等,都可以通过这种方式去实现。
我们这里的例子就简单点,给一个ImageView
加一个水印:
public class WatermarkImageView extends ImageView {
//继承ImageView
private Paint mPaint;
public WatermarkImageView(Context context) {
super(context);
init();
}
public WatermarkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public WatermarkImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//画笔初始化
private void init() {
mPaint = new Paint();//创建画笔
mPaint.setColor(Color.RED);// 设置画笔颜色
mPaint.setTextSize(100);//创建字体大小
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画上水印
canvas.drawText("四月葡萄园博客", 20, getHeight() - 20, mPaint);
}
}
在布局中引用这个WatermarkImageView
,引用自定义的View
需要包名+View名:
<com.april.view.WatermarkImageView
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tuseji"/>
运行程序看看效果:
简单总结一下:继承系统已有View
去扩展功能还是比较简单的,这种方法一般只需重写onDraw()
即可,同时也无需支持wrap_content
和padding
。
3.2 继承View类
继承View
类可以用来实现一些不规则效果,但是需要注意的是,这种方式不仅需要重写onDraw()
,还需要自己去支持wrap_content
和padding
,否则wrap_content
和padding
将不起效。另外,为了方便使用这个自定义View
,我们通常还会提供一些自定义的属性。
这里我们以画一个圆角矩形为例:
public class RoundRectView extends View {
//继承View
private Paint mPaint;
private int mColor=Color.RED;
public RoundRectView(Context context) {
super(context);
init();
}
public RoundRectView(Context context, AttributeSet attrs) {
super(context, attrs);