可以设置文字或图片为背景水印。
核心代码
public class WaterMarkView extends View {
private static final String DEFAULT_SEPARATOR = "///";
private Paint mPaint = new Paint();
private String[] mText;
private Bitmap mImage;
private int mDegrees;
private int mTextColor;
private int mTextSize;
private int mDx;
private int mDy;
private Paint.Align mAlign;
private int textWidth, textHeight;
public WaterMarkView(Context context) {
this(context, null);
}
public WaterMarkView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaterMarkView);
mDegrees = typedArray.getInt(R.styleable.WaterMarkView_water_mark_degree, -30);
String text = typedArray.getString(R.styleable.WaterMarkView_water_mark_text);
int Image = typedArray.getResourceId(R.styleable.WaterMarkView_water_mark_image, R.drawable.ic_avatar);
if (text != null) {
mText = text.split(DEFAULT_SEPARATOR);
} else {
mImage = ((BitmapDrawable) getDrawableExt(Image)).getBitmap();
}
mTextColor = typedArray.getColor(R.styleable.WaterMarkView_water_mark_textColor, Color.parseColor("#33000000"));
mTextSize = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_textSize, 42);
mDx = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dx, 100);
mDy = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dy, 240);
int align = typedArray.getInt(R.styleable.WaterMarkView_water_mark_align, 1);
mAlign = align == 0 ? Paint.Align.LEFT : align == 2 ? Paint.Align.RIGHT : Paint.Align.CENTER;
typedArray.recycle();
setBackgroundColor(Color.TRANSPARENT);
mPaint.setAntiAlias(true);
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.setTextAlign(mAlign);
textWidth = 0;
textHeight = 0;
if (mText != null && mText.length > 0) {
for (String s : mText) {
Rect tvRect = new Rect();
mPaint.getTextBounds(s, 0, s.length(), tvRect);
textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width();
textHeight += (tvRect.height() + 10);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mText != null && mText.length > 0) {
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
if (measuredWidth == 0 || measuredHeight == 0) {
return;
}
int canvasLength = measuredWidth > measuredHeight ? measuredWidth : measuredHeight;
canvas.save();
canvas.rotate(mDegrees, measuredWidth / 2, measuredHeight / 2);
canvas.save();
int y = 0;
boolean odd = true;
while (y < canvasLength + textHeight) {
int x = odd ? 0 : -(textWidth + mDx) / 2;
while (x < canvasLength + textWidth) {
drawTexts(mText, mPaint, canvas, x, y);
x = x + textWidth + mDx;
}
y = y + textHeight + mDy;
odd = !odd;
}
canvas.restore();
} else {
int measuredWidth = getMeasuredWidth();
int measuredHeight = getMeasuredHeight();
if (measuredWidth == 0 || measuredHeight == 0) {
return;
}
int canvasLength = measuredWidth > measuredHeight ? measuredWidth : measuredHeight;
canvas.save();
canvas.rotate(mDegrees, measuredWidth / 2, measuredHeight / 2);
canvas.save();
int y = 0;
boolean odd = true;
while (y < canvasLength) {
int x = odd ? 0 : -mDx / 2;
while (x < canvasLength) {
drawPhoto(mImage, mPaint, canvas, x, y);
x = x + mDx;
}
y = y + mDy;
odd = !odd;
}
canvas.restore();
}
}
private void drawTexts(String[] ss, Paint paint, Canvas canvas, int x, int y) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top = fontMetrics.top;
float bottom = fontMetrics.bottom;
int length = ss.length;
float total = (length - 1) * (bottom - top) + (fontMetrics.descent - fontMetrics.ascent);
float offset = total / 2 - bottom;
for (int i = 0; i < length; i++) {
float yAxis = -(length - i - 1) * (bottom - top) + offset;
canvas.drawText(ss[i], x, y + yAxis + 10, paint);
}
}
private void drawPhoto(Bitmap image, Paint paint, Canvas canvas, int x, int y) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top = fontMetrics.top;
float bottom = fontMetrics.bottom;
float total = (bottom - top) + (fontMetrics.descent - fontMetrics.ascent);
float offset = total / 2 - bottom;
float yAxis = (bottom - top) + offset;
canvas.drawBitmap(image, x, y + yAxis + 10, paint);
}
/**
* 设置水印倾斜角度
*
* @param degrees 倾斜角度(默认:-30)
*/
public void setDegrees(int degrees) {
mDegrees = degrees;
postInvalidate();
}
/**
* 设置水印文字内容
*
* @param text 文字内容
*/
public void setText(String... text) {
mText = text;
textWidth = 0;
textHeight = 0;
if (mText != null && mText.length > 0) {
for (String s : mText) {
Rect tvRect = new Rect();
mPaint.getTextBounds(s, 0, s.length(), tvRect);
textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width();
textHeight += (tvRect.height() + 10);
}
}
postInvalidate();
}
/**
* 设置水印文字内容
*
* @param image 文字内容
*/
public void setPhoto(int image) {
mImage = ((BitmapDrawable) getDrawableExt(image)).getBitmap();
postInvalidate();
}
/**
* 设置水印X轴偏移量(单位:px)
*
* @param dx X轴偏移量(默认:100px)
*/
public void setDx(int dx) {
this.mDx = dx;
postInvalidate();
}
/**
* 设置水印字体颜色
*
* @param textColor 字体颜色(默认:#33000000)
*/
public void setTextColor(int textColor) {
mTextColor = textColor;
mPaint.setColor(mTextColor);
postInvalidate();
}
/**
* 设置水印字体大小(单位:px)
*
* @param textSize 字体大小(默认:42px)
*/
public void setTextSize(int textSize) {
mTextSize = textSize;
mPaint.setTextSize(mTextSize);
postInvalidate();
}
/**
* 设置水印Y轴偏移量(单位:px)
*
* @param dy Y轴偏移量(默认:240px)
*/
public void setDy(int dy) {
this.mDy = dy;
postInvalidate();
}
/**
* 设置水印对齐方式
*
* @param align 对齐方式(默认:Center)
*/
public void setAlign(Paint.Align align) {
this.mAlign = align;
postInvalidate();
}
}
资源文件
<!--warkmark-->
<declare-styleable name="WaterMarkView">
<attr name="water_mark_degree" format="integer|reference" />
<attr name="water_mark_text" format="string|reference" />
<attr name="water_mark_textColor" format="color|reference" />
<attr name="water_mark_image" format="color|reference" />
<attr name="water_mark_textSize" format="dimension|reference" />
<attr name="water_mark_dx" format="dimension|reference" />
<attr name="water_mark_dy" format="dimension|reference" />
<attr name="water_mark_align" format="dimension">
<enum name="LEFT" value="0" />
<enum name="CENTER" value="1" />
<enum name="RIGHT" value="2" />
</attr>
</declare-styleable>
|