上一篇的自定義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,屬性的自定義內容:
<declare-styleable name="DemoImageView01">
<attr name="image" format="reference"/>
<attr name="watermark" format="string"/>
<attr name="watermarkcolor" format="color"/>
<attr name="watermarksize">
<enum name="small" value="0" />
<enum name="normal" value="1" />
<enum name="big" value="2" />
</attr>
</declare-styleable>
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)自定義控件的使用如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:image1="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context="com.jinjin.viewstudy.viewstudy.MainActivity">
<com.jinjin.viewstudy.viewstudy.view.DemoImageView01
android:layout_width="200dp"
android:layout_height="200dp"
android:padding="5dp"
image1:image="@mipmap/image1"
image1:watermark="http://blog.jinjin.net"
image1:watermarkcolor="@android:color/holo_red_dark"
image1:watermarksize="small"/>
<com.jinjin.viewstudy.viewstudy.view.DemoImageView01
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
image1:image="@mipmap/lmj"
image1:watermark="http://blog.jinjin1.net"
image1:watermarkcolor="@android:color/holo_red_dark"
image1:watermarksize="big"/>
<com.jinjin.viewstudy.viewstudy.view.DemoImageView01
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
image1:image="@mipmap/image2"
image1:watermark="http://blog.jinjin1.net"
image1:watermarkcolor="@android:color/holo_red_dark"
image1:watermarksize="big"/>
</LinearLayout>
到此,即可實現上述的顯示效果。
源碼下載: