Android 添加水印View

  • Post author:
  • Post category:其他


可以设置文字或图片为背景水印。

核心代码

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>



版权声明:本文为qq_37220377原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。