• 前言

之前有一篇写过仿钉钉水印的仿钉钉通讯录水印
,不过仔细看了一下,还是略有区别,那一篇改版过很多次了,这里再模仿的更像一些,不过由于之前的实现方式是通过绘制路径然后在路径上绘制文字,但是如果要绘制四条路径的话需要就更麻烦了,害怕以后回过头在看会比较难看懂,这边改成旋转和平移画布的方式绘制倾斜的四段文字。

  • 实现思路

做一个东西首先有思路,才能走下去。
仔细观察后发现钉钉中的水印,呈现四段文字一块,重复平铺的。
ok!首先我们将一块展示四段文字水印的图片绘制出来。
四段文字是两个文字重复的,一个是根据姓名和手机号拼接的,一个是默认的一段文字。
一个就叫 namePhoneText,一个就叫它 appName 吧
这个图片分为四个区域
namePhoneText appName

appName namePhoneText
大概就是按照这种位置展示文字的。

然后文字绘制的时候,通过canvas中的平移和旋转方法,调整到指定位置,然后直接绘制,就不使用之前的方案绘制文字路径的方式了,因为要去计算很多起点和终点的位置,这样后期看代码的时候,会很困难。
将文字绘制完成之后,利用BitmapDrawable 类中的setTileModeXY 设置REPEAT重复平铺展示图,设置到需要设置的view的背景上。
更细节的直接看代码,上也写了不少注释了。

@Inject
    public WaterMarkTextUtil() {

    }
    /**
     * 字的大小 单位sp
     */
    final int textSize = 14;
    /**
     * 一个字所占的像素
     */
    int oneTextPx;
    /**
     * 当前字符串所占的长度
     */
    int textLength;
    /**
     * 默认后缀文字
     */
    String sText = "深圳";
    /**
     * 默认后缀文字的宽高
     */
    int sWitchPx;
    int sHigthPx;
    /**
     * 第二段sText文字距离前一段文字的水平偏移量
     */
    int offset = 80;
    /**图片距离右边的距离*/
    int right = 160;
    /**图片距离上边的距离*/
    int top = 100;
    /**文字旋转的角度*/
    float rotate =20f;
    //设置背景
    public void setWaterMarkTextBg(View view, Context gContext, String gText) {
        view.setBackground(drawTextToBitmap(gContext, gText));

    }

    /**
     * 生成水印文字图片
     */
    public BitmapDrawable drawTextToBitmap(Context mContext, String gText) {

        try {
            TextPaint mTextPaint1 = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            mTextPaint1.density = mContext.getResources().getDisplayMetrics().density;
            oneTextPx = DensityUtil.sp2px(mContext, textSize);
            mTextPaint1.setTextSize(oneTextPx);
            //计算字长
            textLength = (int) mTextPaint1.measureText(gText);
            int stextLength = (int) mTextPaint1.measureText(sText);
            /**拿到字长之后,计算一下斜着显示文字的时候文字所占的长和高*/
            int witchPx = 0;
            int highPx = 0;
            /**默认一段文字的长和高计算*/
            if (sWitchPx == 0) {
                sWitchPx = measurementWitch(stextLength);
                sHigthPx = measurementHigth(stextLength);
            }
            /**传入的文字的长和高计算*/
            witchPx = measurementWitch(textLength);
            highPx = measurementHigth(textLength);
            /**计算显示完整所需占的画图长宽*/
            int bitmapWitch = witchPx + sWitchPx + 2 * oneTextPx + offset;
            int bitmaphigth = (highPx + oneTextPx) * 2;
            //设置画板的时候 增加一个字的长宽
            Bitmap bitmap = Bitmap.createBitmap(bitmapWitch + right,
                    bitmaphigth+(2*top), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            canvas.drawColor(Color.WHITE);
            /**初始化画笔*/
            TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            mTextPaint.density = mContext.getResources().getDisplayMetrics().density;
            mTextPaint.setColor(Color.GRAY);
            mTextPaint.setAlpha(90);
            mTextPaint.setStyle(Paint.Style.FILL);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextAlign(Paint.Align.LEFT);
            mTextPaint.setFakeBoldText(false);
            mTextPaint.setTextSkewX(0);
            mTextPaint.setTextSize(oneTextPx);
            /**
             * ——————————————————————————————————>
             * |    1号绘制区域    |  间  |  2号   |
             * |   gText         |      | appName |
             * |  ①号起点位置     |  隔  |  ②起   |
             * ———————————————————————————————————
             * | 3号      | 间   |   4号绘制区域    |
             * | appName   |      |   gText        |
             * |  ③起     | 隔   |   ④号起        |
             * |———————————————————————————————————
             * V
             */
            /**方式二利用画布平移和旋转绘制*/
            /**先移动到①起点位置*/
            canvas.translate(oneTextPx,highPx+oneTextPx+top);
            /**旋转一定度数 绘制文字*/
            canvas.rotate(-rotate);
            canvas.drawText(gText,0,0,mTextPaint);
            /**恢复原来的度数 再移动画布原点到②号位置*/
            canvas.rotate(rotate);
            canvas.translate(witchPx+offset+oneTextPx,0);
            /**旋转一定度数 绘制文字*/
            canvas.rotate(-rotate);
            canvas.drawText(sText,0,0,mTextPaint);
            /**恢复原来的度数 再移动画布原点到③号位置*/
            canvas.rotate(rotate);
            canvas.translate(-(witchPx+offset+oneTextPx),oneTextPx+highPx+top);
            /**旋转一定度数 绘制文字*/
            canvas.rotate(-rotate);
            canvas.drawText(sText,0,0,mTextPaint);
            /**恢复原来的度数 再移动画布原点到④号位置*/
            canvas.rotate(rotate);
            canvas.translate(sWitchPx+offset+oneTextPx,0);
            /**旋转一定度数 绘制文字*/
            canvas.rotate(-rotate);
            canvas.drawText(gText,0,0,mTextPaint);
            /**保存画布*/
            canvas.save(Canvas.ALL_SAVE_FLAG);
            canvas.restore();
            //生成平铺的bitmapDrawable
            BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
            drawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
            drawable.setDither(true);
            return drawable;
        } catch (Exception e) {

        }
        return null;

    }

    private int measurementWitch(int textLength) {
        //t2 为字长的平方 字长的平方即为三角形的斜边的平方
        int t2 = textLength * textLength;
        //此处设置 三角形的长为高的3倍,那么就是平方之后的9倍,均分为10份 长占9份
        return ceilInt(Math.sqrt(9 * (t2 / 10)));
    }

    private int measurementHigth(int textLength) {
        //t2 为字长的平方 字长的平方即为三角形的斜边的平方
        int t2 = textLength * textLength;
        //此处设置 三角形的长为高的3倍,那么就是平方之后的9倍,均分为10份 长占9份
        return ceilInt(Math.sqrt((t2 / 10)));
    }

    public static int ceilInt(double number) {
        return (int) Math.ceil(number);
    }
  • 再贴一张效果图

java钉钉应用获取通讯录 钉钉写入手机通讯录_通讯录