Last active 1756431645

通过生成一个自定义的Drawble,传入指定的Activity上下文来添加全屏水印浮层

Revision d454bf63426b95cdb0eddf0e9a7ca96a33babe70

Watermark.java Raw
1import android.app.Activity;
2import android.content.res.Resources;
3import android.graphics.Canvas;
4import android.graphics.ColorFilter;
5import android.graphics.Paint;
6import android.graphics.PixelFormat;
7import android.graphics.drawable.Drawable;
8import android.text.TextUtils;
9import android.view.View;
10import android.view.ViewGroup;
11import android.widget.FrameLayout;
12
13import androidx.annotation.IntRange;
14import androidx.annotation.NonNull;
15import androidx.annotation.Nullable;
16
17/**
18 * 水印
19 */
20public 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