App中所有页面添加水印(支持单行和多行)

	比较很少见的奇葩功能,给App所有界面添加水印功能。
	网上有单行,多行的这里为了方便使用,集成了既支持单行又支持多行的功能。
	废话不多说,直接上代码:

一、工具类

public class Watermark {
    /**
     * 水印文本
     */
    private String mText;

    private List<String> labels;
    /**
     * 字体颜色,十六进制形式,例如:0xAEAEAEAE
     */
    private int mTextColor;
    /**
     * 字体大小,单位为sp
     */
    private float mTextSize;
    /**
     * 旋转角度
     */
    private float mRotation;
    private static Watermark sInstance;

    private Watermark() {
        mText = "";
        mTextColor = 0xAEAEAEAE;
        mTextSize = 18;
        mRotation = -25;
    }

    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;
    }

    /**
     * 设置多行水印文本
     *
     * @return Watermark实例
     */
    public Watermark setMultiLine(List<String> lab) {
        labels = lab;
        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) {
        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);
        layout.setAlpha(0.3f);
        rootView.addView(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) {

            if(labels!=null&&labels.size()>0){
                //多行文本
                int width = getBounds().right;
                int height = getBounds().bottom;

                canvas.drawColor(0x00000000);
                mPaint.setColor(mTextColor);

                mPaint.setAntiAlias(true);
                mPaint.setTextSize(ConvertUtils.spToPx(mTextSize));
                canvas.save();
                canvas.rotate(mRotation);
                //计算集合中最长的宽度
                float textWidth = 0;
                for (int i = 0; i < labels.size(); i++) {
                    if(textWidth<mPaint.measureText(labels.get(i))){
                        textWidth = mPaint.measureText(labels.get(i));
                    }
                }
                int index = 0;
                for (int positionY = height / 10; positionY <= height; positionY += height / 10+80) {
                    float fromX = -width + (index++ % 2) * textWidth;
                    for (float positionX = fromX; positionX < width; positionX += textWidth * 2) {
                        int spacing = 0;//间距
                        for(String label:labels){
                            canvas.drawText(label, positionX, positionY+spacing, mPaint);
                            spacing = spacing+50;
                        }

                    }
                }
                canvas.restore();
            }else if(!TextUtils.isEmpty(mText)){
                //单行文本
                int width = getBounds().right;
                int height = getBounds().bottom;
                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();
            }

        }

        @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;
        }

    }
}

二、ConvertUtils工具类

public class ConvertUtils {
/**
     * 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);
    }
 }

三、使用方法(在BaseActivity中使用,所有Activity继承该类即可)
需要注意的是在BaseActiviy中的setContentView(int layoutResId)中使用

单行水印:方式一

@Override
    public void setContentView(int layoutResID) {
    	super.setContentView(layoutResID);
				Watermark.getInstance()
                .setText("水印的内容")
                .setTextColor(0xAE000000)
                .setTextSize(14)
                .setRotation(-30)
                .show(this);
    }

方式二:其实多行水印只放入集合中一条也可实现.

多行水印

@Override
    public void setContentView(int layoutResID) {
    	super.setContentView(layoutResID);
        String dateTimeFormat = DateUtil.getDateTimeFormat(new Date());
        Staff staff = ProjectNameApp.getInstance().getStaff();
        // 可以自定义水印文字颜色、大小和旋转角度
        List<String> labels = new ArrayList<>();
        labels.add(staff.getName());
        labels.add(staff.getMobile());
        labels.add(dateTimeFormat);
        Watermark.getInstance()
                .setMultiLine(labels)
                .setTextColor(0xAE000000)
                .setTextSize(14)
                .setRotation(-30)
                .show(this);
    }

希望能帮助到各位,你的一个点赞都是对我的支持,谢谢!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成功之路必定艰辛

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值