上一篇的自定义View中的测量绘制 http://blog.csdn.net/jinjin10086/article/details/54947301
在此基础上,本次在此基础上继续进行学习。
本次的目标是在上一篇的基础上给普通的图片加上水印,实际的应用如csdn上传图片、微信公众号上传图片,都会自动给图片加上水印,当然本次只是给加上水印,可设置水印的颜色,内容,规格大小(small为14号字体,normal为16号字体,big为18号字体)等。
实现的效果如下:
接下来解析具体得实现过程:
1)和上次的一样,继承自View重写其构造方法,如下:
public DemoImageView01(Context context) {
this(context,null);
}
public DemoImageView01(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public DemoImageView01(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
2)自定义属性如下:
1,属性的自定义内容:
2,取到相关的属性如下(对于图片资源进行直接解析):
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.DemoImageView01,defStyleAttr,0);
for (int i = 0; i < array.getIndexCount(); i++) {
int attr = array.getIndex(i);
switch (attr){
case R.styleable.DemoImageView01_image:
Log.d("test","image-->" + array.getResourceId(attr,0));
mImageSrc = BitmapFactory.decodeResource(getResources(),array.getResourceId(attr,0));
break;
case R.styleable.DemoImageView01_watermark:
mWatermark = array.getString(attr);
break;
case R.styleable.DemoImageView01_watermarkcolor:
mWatermarkColor = array.getColor(attr, Color.BLUE);
break;
case R.styleable.DemoImageView01_watermarksize:
int style = array.getInt(attr,0);
switch (style){
case 0:
mWatermarkSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 14, getResources().getDisplayMetrics());
break;
case 1:
mWatermarkSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics());
break;
case 2:
mWatermarkSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 18, getResources().getDisplayMetrics());
break;
default:
break;
}
break;
default:
break;
}
}
3)初始化画笔及绘制范围如下:
mPaint = new Paint();
mBound = new Rect();
mWaterMarkBound = new Rect();
mPaint.setTextSize(mWatermarkSize);
mPaint.getTextBounds(mWatermark, 0, mWatermark.length(), mWaterMarkBound);
4)测量,重写方法onMeasure如下:
@Override
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);
if (widthMode == MeasureSpec.EXACTLY){
mWidth = widthSize;
}else {
//图片的宽度 (注:水印覆盖在图片上,不占宽度)
int desire = getPaddingLeft() + getPaddingRight() + mImageSrc.getWidth();
mWidth = Math.min(desire,widthSize);
}
if (heightMode == MeasureSpec.EXACTLY){
mHeight = heightSize;
}else {
///图片的宽度 (注:水印覆盖在图片上,不占高度)
int desire = getPaddingTop() + getPaddingBottom() + mImageSrc.getHeight();
mHeight = Math.min(desire,heightSize);
}
Log.d("test","mWidth" + mWidth);
Log.d("test","mHeight" + mHeight);
setMeasuredDimension(mWidth,mHeight);
}
5)绘制,重写onDraw方法如下:
@Override
protected void onDraw(Canvas canvas) {
/*
整体绘制区域的规定
*/
mBound.left = getPaddingLeft();
mBound.right = mWidth - getPaddingRight();
mBound.top = getPaddingTop();
mBound.bottom = mHeight - getPaddingBottom();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.YELLOW);
//绘制图片
canvas.drawBitmap(mImageSrc,null,mBound,mPaint);
mPaint.setTextSize(mWatermarkSize);
mPaint.getTextBounds(mWatermark,0,mWatermark.length(),mWaterMarkBound);
mPaint.setColor(mWatermarkColor);
/*
如果水印的宽度 大于整体区域的宽度
*/
if (mWaterMarkBound.width() > mWidth){
TextPaint paint = new TextPaint(mPaint);
String mWaterMarkNow = TextUtils.ellipsize(mWatermark,paint,(float) (mWidth - getPaddingLeft() - getPaddingRight()), TextUtils.TruncateAt.END).toString();
canvas.drawText(mWaterMarkNow,getPaddingLeft(), mHeight - getPaddingBottom() - mWaterMarkBound.height(), mPaint);
}else {
canvas.drawText(mWatermark, mWidth - mWaterMarkBound.width() - getPaddingRight() , mHeight - getPaddingBottom() - mWaterMarkBound.height(), mPaint);
}
}
6)自定义控件的使用如下:
源码下载:
MyDemo