• 页面中满屏水印


    1. 前言

    现在市面上,有很多APP在一些关键页面上会有水印,水印一般都是一些身份相关的信息,这样可以保证截屏后的图片具有识别性,能够知道这张截图是谁截取的。

    2. 具体实现

    为了能够方便地在任意页面上加水印,所以应该采取用Java代码来实现,而不是在XML布局文件里面写。大概思路是,首先获取当前页面的底层布局,然后在布局最上层添加一个全屏的带有水印的FrameLayout布局。这个全屏的带有水印的FrameLayout布局,我们可以在XML写。很多博客文章都是介绍这种方式来写水印,不过大多数都没做适配,特别是横屏显示时,水印效果很不好。所以我这里用Java代码来画水印。自定义一个Drawable,把它当作水印,然后设置到FrameLayout布局的背景,这样就行了。相关代码如下所示:

    1. import android.app.Activity;
    2. import android.graphics.Canvas;
    3. import android.graphics.ColorFilter;
    4. import android.graphics.Paint;
    5. import android.graphics.PixelFormat;
    6. import android.graphics.drawable.Drawable;
    7. import android.view.ViewGroup;
    8. import android.widget.FrameLayout;
    9. import androidx.annotation.Nullable;
    10. public class Watermark {
    11. /*** 水印文本*/
    12. private String mText;
    13. /*** 字体颜色,十六进制形式,例如:0xAEAEAEAE*/
    14. private int mTextColor;
    15. /*** 字体大小,单位为sp*/
    16. private float mTextSize;
    17. /*** 旋转角度*/
    18. private float mRotation;
    19. private static Watermark sInstance;
    20. private Watermark() {
    21. mText = "";
    22. mTextColor = 0xAEAEAEAE;
    23. mTextSize = 18;
    24. mRotation = -25;
    25. }
    26. public static Watermark getInstance() {
    27. if (sInstance == null) {
    28. synchronized (Watermark.class) {
    29. sInstance = new Watermark();
    30. }
    31. }
    32. return sInstance;
    33. }
    34. /*** 设置水印文本** @param text 文本* @return Watermark实例*/
    35. public Watermark setText(String text) {
    36. mText = text;
    37. return sInstance;
    38. }
    39. /*** 设置字体颜色** @param color 颜色,十六进制形式,例如:0xAEAEAEAE* @return Watermark实例*/
    40. public Watermark setTextColor(int color) {
    41. mTextColor = color;
    42. return sInstance;
    43. }
    44. /*** 设置字体大小** @param size 大小,单位为sp* @return Watermark实例*/
    45. public Watermark setTextSize(float size) {
    46. mTextSize = size;
    47. return sInstance;
    48. }
    49. /*** 设置旋转角度** @param degrees 度数* @return Watermark实例*/
    50. public Watermark setRotation(float degrees) {
    51. mRotation = degrees;
    52. return sInstance;
    53. }
    54. /*** 显示水印,铺满整个页面** @param activity 活动*/
    55. public void show(Activity activity) {
    56. show(activity, mText);
    57. }
    58. /*** 显示水印,铺满整个页面** @param activity 活动* @param text 水印*/
    59. public void show(Activity activity, String text) {
    60. WatermarkDrawable drawable = new WatermarkDrawable();
    61. drawable.mText = text;
    62. drawable.mTextColor = mTextColor;
    63. drawable.mTextSize = mTextSize;
    64. drawable.mRotation = mRotation;
    65. ViewGroup rootView = activity.findViewById(android.R.id.content);
    66. FrameLayout layout = new FrameLayout(activity);
    67. layout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    68. layout.setBackground(drawable);
    69. rootView.addView(layout);
    70. }
    71. class WatermarkDrawable extends Drawable {
    72. private Paint mPaint;
    73. /*** 水印文本*/
    74. private String mText;
    75. /*** 字体颜色,十六进制形式,例如:0xAEAEAEAE*/
    76. private int mTextColor;
    77. /*** 字体大小,单位为sp*/
    78. private float mTextSize;
    79. /*** 旋转角度*/
    80. private float mRotation;
    81. WatermarkDrawable() {
    82. mPaint = new Paint();
    83. }
    84. @Override
    85. public void draw(Canvas canvas) {
    86. int width = getBounds().right;
    87. int height = getBounds().bottom;
    88. int diagonal = (int) Math.sqrt(width * width + height * height); // 对角线的长度mPaint.setColor(mTextColor);mPaint.setTextSize(ConvertUtils.spToPx(mTextSize)); // ConvertUtils.spToPx()这个方法是将sp转换成px,ConvertUtils这个工具类在我提供的demo里面有mPaint.setAntiAlias(true);float textWidth = mPaint.measureText(mText);canvas.drawColor(0x00000000);canvas.rotate(mRotation);int index = 0;float fromX;// 以对角线的长度来做高度,这样可以保证竖屏和横屏整个屏幕都能布满水印for (int positionY = diagonal / 10; positionY <= diagonal; positionY += diagonal / 10) {fromX = -width + (index++ % 2) * textWidth; // 上下两行的X轴起始点不一样,错开显示for (float positionX = fromX; positionX < width; positionX += textWidth * 2) {canvas.drawText(mText, positionX, positionY, mPaint);}}canvas.save();canvas.restore();}@Overridepublic void setAlpha(@IntRange(from = 0, to = 255) int alpha) {}@Overridepublic void setColorFilter(@Nullable ColorFilter colorFilter) {}@Overridepublic int getOpacity() {return PixelFormat.TRANSLUCENT;}}
    89. }
    90. @Override
    91. public void setAlpha(int alpha) {
    92. }
    93. @Override
    94. public void setColorFilter(@Nullable ColorFilter colorFilter) {
    95. }
    96. @Override
    97. public int getOpacity() {
    98. return PixelFormat.UNKNOWN;
    99. }
    100. }
    101. }

    3. 使用方式

    为了保证能够在当前页面的最顶层加水印,应该在 setContentView() 后面添加水印

    1. @Overrideprotected void onCreate(Bundle savedInstanceState) {
    2. super.onCreate(savedInstanceState);
    3. setContentView(R.layout.activity_main);
    4. Watermark.getInstance().show(this, "Fantasy BlogDemo");// 可以自定义水印文字颜色、大小和旋转角度
    5. Watermark.getInstance().setText("Fantasy BlogDemo").setTextColor(0xAE000000) .setTextSize(16).setRotation(-30).show(this);}

  • 相关阅读:
    物联网AI MicroPython学习之语法 bluetooth蓝牙
    Android 获取某月所有的日期和星期
    OpenFeign快速入门及使用
    机器学习中的几种交叉验证方法(5种)
    lightdb 支持兼容Oracle的to_clob函数
    6种自媒体赚钱方法!
    openlayers点标记只在视图内展示,视图外不展示,用于大量数据展示
    Java多线程上——基本概念及操作
    为你的项目搭建sentry并且通过企微推送
    Unity的BuildPlayerProcessor:深入解析与实用案例
  • 原文地址:https://blog.csdn.net/tianhongfan10106/article/details/132810773