项目中的实践:
- 红点提示ImageView的实现, ImageViewWithDot
- 正方形ImageView的实现, SquareImageView
这篇文章讲的还是很清晰的
一个规范的自定义View——Android开发艺术探索笔记
http://blog.csdn.net/l664675249/article/details/50787973
自定义View的核心是: 重写View的onDraw和onMeasure方法.
重写onDraw()的目的
是实现真正的在传进来的canvas对象上绘制图像.
ImageViewWithDot.java
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (showRedPoint) {
canvas.drawCircle(getWidth() / 1.3f, getHeight() / 3.4f, mCircleRadius, mPaint);
}
}
注意, 如果是直接继承自View的话, 要在重写的onDraw()中去处理有padding的情况.
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int paddingTop = getPaddingTop();
final int paddingBottom = getPaddingBottom();
int width = getWidth() - paddingLeft - paddingRight;
int height = getHeight() - paddingTop - paddingBottom;
int radius = Math.min(width, height) / 2;
canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2,
radius, mPaint);
}
重写onMeasure()的目的
直接继承View或ViewGroup的需要自己通过重写onMeasure()处理wrap_content,否则使用wrap_content就相当于使用match_partent.
也就是说像红点提示ImageViewWithDot直接继承自ImageView,也就没必要自己重写onMeasure()了.
对onMeasure()的重写代码基本就是模板化, 不用刻意去记, 只需要记住重写的目的就可以了, 用的时候直接copy过来稍加修改就行.
@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);
if (widthSpecMode == MeasureSpec.AT_MOST
&& heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(200, 200);
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(200, heightSpecSize);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, 200);
}
}
通过重写onMeasure()也可以达到一些特殊的目的,
例如, 不管使用什么尺寸的bitmap设置给ImageView, 让ImageView的显示保持为正方形.
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//使用宽度值去设置高度值
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
-----DONE-------------