自定义View 水印布局 WaterMark 前景色

Posted baiqiantao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义View 水印布局 WaterMark 前景色相关的知识,希望对你有一定的参考价值。

自定义View 水印布局 WaterMark 前景色


目录

项目中的使用案例

项目中要求在所有页面都添加水印,这种情况下可以在BaseActivity中将水印布局设为根布局

前景色样式:
技术分享图片
背景色样式:
技术分享图片

布局:

<com.bqt.lock.MarkFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mark_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:mark_is_foreground="false"
    app:mark_show_value="包青天"
    app:mark_textcolor="#fff">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#f00"
        android:gravity="center"/>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_marginTop="200dp"
        android:scaleType="centerCrop"
        android:src="@drawable/icon"/>

</com.bqt.lock.MarkFrameLayout>

水印布局 MarkFrameLayout

绘制水印时,可以选择在onDrawForeground上绘制前景色(盖在所有View的上面),也可以选择在onDraw上绘制背景色(会被所有View的背景遮盖)。
如果需要用到继承自其他其他 Layout 的水印布局,则只需将继承的类改为RelativeLayoutLinearLayout即可,其他什么都不需要更改。

public class MarkFrameLayout extends FrameLayout {

    private static final int DEFAULT_DEGRESES = -15;//水印倾斜角度
    private static final int DEFAULT_MARK_PAINT_COLOR = Color.parseColor("#FFCCCCCC");//水印颜色
    private static final int DEFAULT_ALPHA = (int) (0.5 * 255);//水印透明度
    private static final String DEFAULT_MARK_SHOW_VALUE = "[水印]";//水印内容

    private boolean showMark = true;
    private float mMarkTextSize;
    private int mMarkTextColor;
    private boolean mMarkLayerIsForeground; //水印绘制在控件背景上,还是前景色上
    private float mDegrees;
    private int mVerticalSpacing;
    private int mHorizontalSpacing;
    private int mMarkPainAlpha;
    private String mMarkValue;
    private TextPaint mMarkPaint;
    private Bitmap mMarkBitmap;

    public MarkFrameLayout(@NonNull Context context) {
        this(context, null);
    }

    public MarkFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        if (showMark) {
            int defaultMarkTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics());
            int defaultSpacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics());

            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MarkFrameLayout);
            mDegrees = a.getInteger(R.styleable.MarkFrameLayout_mark_rotate_degrees, DEFAULT_DEGRESES);
            mMarkTextColor = a.getColor(R.styleable.MarkFrameLayout_mark_textcolor, DEFAULT_MARK_PAINT_COLOR);
            mMarkTextSize = a.getDimension(R.styleable.MarkFrameLayout_mark_textsize, defaultMarkTextSize);
            mMarkPainAlpha = a.getInt(R.styleable.MarkFrameLayout_mark_alpha, DEFAULT_ALPHA);
            mMarkLayerIsForeground = a.getBoolean(R.styleable.MarkFrameLayout_mark_is_foreground, true);//默认绘制在前景色上
            mHorizontalSpacing = (int) a.getDimension(R.styleable.MarkFrameLayout_mark_hor_spacing, defaultSpacing);
            mVerticalSpacing = (int) a.getDimension(R.styleable.MarkFrameLayout_mark_ver_spacing, defaultSpacing);
            mMarkValue = a.getString(R.styleable.MarkFrameLayout_mark_show_value);
            mMarkValue = TextUtils.isEmpty(mMarkValue) ? DEFAULT_MARK_SHOW_VALUE : mMarkValue;

            a.recycle();
            initWaterPaint();
            setForeground(new ColorDrawable(Color.TRANSPARENT)); //重置前景色透明
        }
    }

    @Override
    public void onDrawForeground(Canvas canvas) {
        super.onDrawForeground(canvas);
        if (showMark && mMarkLayerIsForeground) {
            drawMark(canvas); //绘制前景色
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (showMark && !mMarkLayerIsForeground) {
            drawMark(canvas); //绘制被景色
        }
    }

    private void initWaterPaint() {
        //初始化Mark的Paint
        mMarkPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); //mMarkPaint.setAntiAlias(true)
        mMarkPaint.setColor(mMarkTextColor);
        mMarkPaint.setAlpha(mMarkPainAlpha);
        mMarkPaint.setTextSize(mMarkTextSize);
        //初始化MarkBitmap
        Paint.FontMetrics fontMetrics = mMarkPaint.getFontMetrics();
        int textHeight = (int) (fontMetrics.bottom - fontMetrics.top);
        int textLength = (int) mMarkPaint.measureText(mMarkValue);
        mMarkBitmap = Bitmap.createBitmap(textLength + 2 * mHorizontalSpacing,
                textHeight + mVerticalSpacing * 2, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mMarkBitmap);
        canvas.drawText(mMarkValue, mHorizontalSpacing, mVerticalSpacing, mMarkPaint);
    }

    private void drawMark(Canvas canvas) {
        int maxSize = Math.max(getMeasuredWidth(), getMeasuredHeight());
        mMarkPaint.setShader(new BitmapShader(mMarkBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
        canvas.save();
        canvas.translate(-(maxSize - getMeasuredWidth()) / 2, 0);
        canvas.rotate(mDegrees, maxSize / 2, maxSize / 2);
        canvas.drawRect(new RectF(0, 0, maxSize, maxSize), mMarkPaint);
        canvas.restore();
    }

    public void setShowMark(boolean showMark) {
        this.showMark = showMark;
        invalidate();
    }
}

自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="basicres_MarkFrameLayout">
        <attr name="basicres_mark_rotate_degrees" format="integer" />
        <attr name="basicres_mark_textcolor" format="color|reference" />
        <attr name="basicres_mark_textsize" format="dimension" />
        <attr name="basicres_mark_alpha" format="integer" />
        <attr name="basicres_mark_is_foreground" format="boolean" />
        <attr name="basicres_mark_hor_spacing" format="dimension" />
        <attr name="basicres_mark_ver_spacing" format="dimension" />
        <attr name="basicres_mark_show_value" format="string" />
    </declare-styleable>

</resources>

2018-10-13 11:59:36 星期六








以上是关于自定义View 水印布局 WaterMark 前景色的主要内容,如果未能解决你的问题,请参考以下文章

uniapp 自定义图片水印插件 Ba-Watermark

Android 自定义相机 Camera 预览变形拉伸问题

水印位置问题

WaterMark.js给网页加水印

js 添加水印方法

如何在word中添加多行水印