上一篇的自定义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>
到此,即可实现上述的显示效果。
源码下载:Demo
作者:jinjin10086 发表于2017/2/10 11:42:43 原文链接
阅读:5 评论:0 查看评论