Watermark.java
· 6.3 KiB · Java
Исходник
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* 水印
*/
public class Watermark {
/**
* 水印文本
*/
private String mText;
/**
* 字体颜色(argb),十六进制形式,例如:0xAEAEAEAE
*/
private int mTextColor;
/**
* 字体大小,单位为sp
*/
private float mTextSize;
/**
* 旋转角度
*/
private float mRotation;
private static Watermark sInstance;
private Watermark() {
mText = "";
mTextColor = 0xAECECECE;
mTextSize = 18;
mRotation = -45;
}
public static Watermark getInstance() {
if (sInstance == null) {
synchronized (Watermark.class) {
sInstance = new Watermark();
}
}
return sInstance;
}
/**
* 设置水印文本
*
* @param text 文本
* @return Watermark实例
*/
public Watermark setText(String text) {
mText = text;
return sInstance;
}
/**
* 设置字体颜色
*
* @param color 颜色,十六进制形式,例如:0xAEAEAEAE
* @return Watermark实例
*/
public Watermark setTextColor(int color) {
mTextColor = color;
return sInstance;
}
/**
* 设置字体大小
*
* @param size 大小,单位为sp
* @return Watermark实例
*/
public Watermark setTextSize(float size) {
mTextSize = size;
return sInstance;
}
/**
* 设置旋转角度
*
* @param degrees 度数
* @return Watermark实例
*/
public Watermark setRotation(float degrees) {
mRotation = degrees;
return sInstance;
}
/**
* 显示水印,铺满整个页面
*
* @param activity 活动
*/
public void show(Activity activity) {
show(activity, mText);
}
/**
* 显示水印,铺满整个页面
*
* @param activity 活动
* @param text 水印
*/
public void show(Activity activity, String text) {
if (activity == null || TextUtils.isEmpty(text)) {
return;
}
WatermarkDrawable drawable = new WatermarkDrawable();
drawable.mText = text;
drawable.mTextColor = mTextColor;
drawable.mTextSize = mTextSize;
drawable.mRotation = mRotation;
ViewGroup rootView = activity.findViewById(android.R.id.content);
FrameLayout layout = new FrameLayout(activity);
layout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
layout.setBackground(drawable);
rootView.addView(layout);
}
/**
* 显示水印,只给指定的View设置水印背景
* @param view
* @param text
*/
public void show(View view, String text) {
if (view == null || TextUtils.isEmpty(text)) {
return;
}
WatermarkDrawable drawable = build(text);
view.setBackground(drawable);
}
private WatermarkDrawable build(String text){
WatermarkDrawable drawable = new WatermarkDrawable();
drawable.mText = text;
drawable.mTextColor = mTextColor;
drawable.mTextSize = mTextSize;
drawable.mRotation = mRotation;
return drawable;
}
public FrameLayout buildWaterMarkFrame(Activity activity, String text) {
FrameLayout layout = new FrameLayout(activity);
layout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
layout.setBackground(build(text));
return layout;
}
private class WatermarkDrawable extends Drawable {
private Paint mPaint;
/**
* 水印文本
*/
private String mText;
/**
* 字体颜色,十六进制形式,例如:0xAEAEAEAE
*/
private int mTextColor;
/**
* 字体大小,单位为sp
*/
private float mTextSize;
/**
* 旋转角度
*/
private float mRotation;
private WatermarkDrawable() {
mPaint = new Paint();
}
@Override
public void draw(@NonNull Canvas canvas) {
int width = getBounds().right;
int height = getBounds().bottom;
int diagonal = (int) Math.sqrt(width * width + height * height); // 对角线的长度
mPaint.setColor(mTextColor);
mPaint.setTextSize(spToPx(mTextSize));
mPaint.setAntiAlias(true);
float textWidth = mPaint.measureText(mText);
canvas.drawColor(0x00000000);
canvas.rotate(mRotation);
int index = 0;
float fromX;
for (int positionY = diagonal / 7; positionY <= diagonal; positionY += diagonal / 7) {
fromX = -width + (index++ % 2) * textWidth; // 上下两行的X轴起始点不一样,错开显示
for (float positionX = fromX; positionX < width; positionX += textWidth * 3) {
canvas.drawText(mText, positionX, positionY, mPaint);
}
}
canvas.save();
canvas.restore();
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
/**
* Value of sp to value of px.
*
* @param spValue The value of sp.
* @return value of px
*/
public static int spToPx(float spValue) {
float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
| 1 | import android.app.Activity; |
| 2 | import android.content.res.Resources; |
| 3 | import android.graphics.Canvas; |
| 4 | import android.graphics.ColorFilter; |
| 5 | import android.graphics.Paint; |
| 6 | import android.graphics.PixelFormat; |
| 7 | import android.graphics.drawable.Drawable; |
| 8 | import android.text.TextUtils; |
| 9 | import android.view.View; |
| 10 | import android.view.ViewGroup; |
| 11 | import android.widget.FrameLayout; |
| 12 | |
| 13 | import androidx.annotation.IntRange; |
| 14 | import androidx.annotation.NonNull; |
| 15 | import androidx.annotation.Nullable; |
| 16 | |
| 17 | /** |
| 18 | * 水印 |
| 19 | */ |
| 20 | public class Watermark { |
| 21 | /** |
| 22 | * 水印文本 |
| 23 | */ |
| 24 | private String mText; |
| 25 | /** |
| 26 | * 字体颜色(argb),十六进制形式,例如:0xAEAEAEAE |
| 27 | */ |
| 28 | private int mTextColor; |
| 29 | /** |
| 30 | * 字体大小,单位为sp |
| 31 | */ |
| 32 | private float mTextSize; |
| 33 | /** |
| 34 | * 旋转角度 |
| 35 | */ |
| 36 | private float mRotation; |
| 37 | private static Watermark sInstance; |
| 38 | |
| 39 | private Watermark() { |
| 40 | mText = ""; |
| 41 | mTextColor = 0xAECECECE; |
| 42 | mTextSize = 18; |
| 43 | mRotation = -45; |
| 44 | } |
| 45 | |
| 46 | public static Watermark getInstance() { |
| 47 | if (sInstance == null) { |
| 48 | synchronized (Watermark.class) { |
| 49 | sInstance = new Watermark(); |
| 50 | } |
| 51 | } |
| 52 | return sInstance; |
| 53 | } |
| 54 | |
| 55 | /** |
| 56 | * 设置水印文本 |
| 57 | * |
| 58 | * @param text 文本 |
| 59 | * @return Watermark实例 |
| 60 | */ |
| 61 | public Watermark setText(String text) { |
| 62 | mText = text; |
| 63 | return sInstance; |
| 64 | } |
| 65 | |
| 66 | /** |
| 67 | * 设置字体颜色 |
| 68 | * |
| 69 | * @param color 颜色,十六进制形式,例如:0xAEAEAEAE |
| 70 | * @return Watermark实例 |
| 71 | */ |
| 72 | public Watermark setTextColor(int color) { |
| 73 | mTextColor = color; |
| 74 | return sInstance; |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * 设置字体大小 |
| 79 | * |
| 80 | * @param size 大小,单位为sp |
| 81 | * @return Watermark实例 |
| 82 | */ |
| 83 | public Watermark setTextSize(float size) { |
| 84 | mTextSize = size; |
| 85 | return sInstance; |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * 设置旋转角度 |
| 90 | * |
| 91 | * @param degrees 度数 |
| 92 | * @return Watermark实例 |
| 93 | */ |
| 94 | public Watermark setRotation(float degrees) { |
| 95 | mRotation = degrees; |
| 96 | return sInstance; |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * 显示水印,铺满整个页面 |
| 101 | * |
| 102 | * @param activity 活动 |
| 103 | */ |
| 104 | public void show(Activity activity) { |
| 105 | show(activity, mText); |
| 106 | } |
| 107 | |
| 108 | /** |
| 109 | * 显示水印,铺满整个页面 |
| 110 | * |
| 111 | * @param activity 活动 |
| 112 | * @param text 水印 |
| 113 | */ |
| 114 | public void show(Activity activity, String text) { |
| 115 | if (activity == null || TextUtils.isEmpty(text)) { |
| 116 | return; |
| 117 | } |
| 118 | WatermarkDrawable drawable = new WatermarkDrawable(); |
| 119 | drawable.mText = text; |
| 120 | drawable.mTextColor = mTextColor; |
| 121 | drawable.mTextSize = mTextSize; |
| 122 | drawable.mRotation = mRotation; |
| 123 | |
| 124 | ViewGroup rootView = activity.findViewById(android.R.id.content); |
| 125 | FrameLayout layout = new FrameLayout(activity); |
| 126 | layout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, |
| 127 | ViewGroup.LayoutParams.MATCH_PARENT)); |
| 128 | layout.setBackground(drawable); |
| 129 | rootView.addView(layout); |
| 130 | } |
| 131 | |
| 132 | /** |
| 133 | * 显示水印,只给指定的View设置水印背景 |
| 134 | * @param view |
| 135 | * @param text |
| 136 | */ |
| 137 | public void show(View view, String text) { |
| 138 | if (view == null || TextUtils.isEmpty(text)) { |
| 139 | return; |
| 140 | } |
| 141 | WatermarkDrawable drawable = build(text); |
| 142 | view.setBackground(drawable); |
| 143 | } |
| 144 | |
| 145 | private WatermarkDrawable build(String text){ |
| 146 | WatermarkDrawable drawable = new WatermarkDrawable(); |
| 147 | drawable.mText = text; |
| 148 | drawable.mTextColor = mTextColor; |
| 149 | drawable.mTextSize = mTextSize; |
| 150 | drawable.mRotation = mRotation; |
| 151 | return drawable; |
| 152 | } |
| 153 | |
| 154 | public FrameLayout buildWaterMarkFrame(Activity activity, String text) { |
| 155 | FrameLayout layout = new FrameLayout(activity); |
| 156 | layout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, |
| 157 | ViewGroup.LayoutParams.MATCH_PARENT)); |
| 158 | layout.setBackground(build(text)); |
| 159 | return layout; |
| 160 | } |
| 161 | |
| 162 | private class WatermarkDrawable extends Drawable { |
| 163 | private Paint mPaint; |
| 164 | /** |
| 165 | * 水印文本 |
| 166 | */ |
| 167 | private String mText; |
| 168 | /** |
| 169 | * 字体颜色,十六进制形式,例如:0xAEAEAEAE |
| 170 | */ |
| 171 | private int mTextColor; |
| 172 | /** |
| 173 | * 字体大小,单位为sp |
| 174 | */ |
| 175 | private float mTextSize; |
| 176 | /** |
| 177 | * 旋转角度 |
| 178 | */ |
| 179 | private float mRotation; |
| 180 | |
| 181 | private WatermarkDrawable() { |
| 182 | mPaint = new Paint(); |
| 183 | } |
| 184 | |
| 185 | @Override |
| 186 | public void draw(@NonNull Canvas canvas) { |
| 187 | int width = getBounds().right; |
| 188 | int height = getBounds().bottom; |
| 189 | int diagonal = (int) Math.sqrt(width * width + height * height); // 对角线的长度 |
| 190 | |
| 191 | mPaint.setColor(mTextColor); |
| 192 | mPaint.setTextSize(spToPx(mTextSize)); |
| 193 | mPaint.setAntiAlias(true); |
| 194 | float textWidth = mPaint.measureText(mText); |
| 195 | |
| 196 | canvas.drawColor(0x00000000); |
| 197 | canvas.rotate(mRotation); |
| 198 | |
| 199 | int index = 0; |
| 200 | float fromX; |
| 201 | for (int positionY = diagonal / 7; positionY <= diagonal; positionY += diagonal / 7) { |
| 202 | fromX = -width + (index++ % 2) * textWidth; // 上下两行的X轴起始点不一样,错开显示 |
| 203 | for (float positionX = fromX; positionX < width; positionX += textWidth * 3) { |
| 204 | canvas.drawText(mText, positionX, positionY, mPaint); |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | canvas.save(); |
| 209 | canvas.restore(); |
| 210 | } |
| 211 | |
| 212 | @Override |
| 213 | public void setAlpha(@IntRange(from = 0, to = 255) int alpha) { |
| 214 | } |
| 215 | |
| 216 | @Override |
| 217 | public void setColorFilter(@Nullable ColorFilter colorFilter) { |
| 218 | } |
| 219 | |
| 220 | @Override |
| 221 | public int getOpacity() { |
| 222 | return PixelFormat.TRANSLUCENT; |
| 223 | } |
| 224 | |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * Value of sp to value of px. |
| 229 | * |
| 230 | * @param spValue The value of sp. |
| 231 | * @return value of px |
| 232 | */ |
| 233 | public static int spToPx(float spValue) { |
| 234 | float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity; |
| 235 | return (int) (spValue * fontScale + 0.5f); |
| 236 | } |
| 237 | } |
| 238 |