private static final String DEFAULT_SEPARATOR = “///”;
private TextPaint mTextPaint = new TextPaint();
private String[] mText;
private int mDegrees;
private int mTextColor;
private int mTextSize=35;
private boolean mTextBold;
private int mDx;
private int mDy;
private Paint.Align mAlign;
private boolean mSync;
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, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDegrees() : -30);
String text = typedArray.getString(R.styleable.WaterMarkView_water_mark_text);
if (text != null) {
mText = text.split(DEFAULT_SEPARATOR);
}
mTextColor = typedArray.getColor(R.styleable.WaterMarkView_water_mark_textColor, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getTextColor() : Color.parseColor(“#33000000”));
mTextSize = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_textSize, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getTextSize() : 42);
mTextBold = typedArray.getBoolean(R.styleable.WaterMarkView_water_mark_textBold, WaterMarkManager.INFO != null && WaterMarkManager.INFO.isTextBold());
mDx = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dx, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDx() : 100);
mDy = typedArray.getDimensionPixelSize(R.styleable.WaterMarkView_water_mark_dy, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getDy() : 240);
int align = typedArray.getInt(R.styleable.WaterMarkView_water_mark_align, WaterMarkManager.INFO != null ? WaterMarkManager.INFO.getAlignInt() : 1);
mAlign = align == 0 ? Paint.Align.LEFT : align == 2 ? Paint.Align.RIGHT : Paint.Align.CENTER;
mSync = typedArray.getBoolean(R.styleable.WaterMarkView_water_mark_sync, true);
typedArray.recycle();
setBackgroundColor(Color.TRANSPARENT);
mTextPaint.setAntiAlias(true);
mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setTypeface(mTextBold ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
mTextPaint.setTextAlign(mAlign);
mText = mText == null && mSync ? WaterMarkManager.CONTENT : mText;
textWidth = 0;
textHeight = 0;
if (mText != null && mText.length > 0) {
for (String s : mText) {
Rect tvRect = new Rect();
mTextPaint.getTextBounds(s, 0, s.length(), tvRect);
textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width();
textHeight += (tvRect.height() + 10);
}
}
if (mSync) {
WaterMarkManager.LIST.add(this);
}
}
@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, mTextPaint, canvas, x, y);
x = x + textWidth + mDx;
}
y = y + textHeight + 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);
}
}
/**
-
设置水印文字内容
-
@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();
mTextPaint.getTextBounds(s, 0, s.length(), tvRect);
textWidth = textWidth > tvRect.width() ? textWidth : tvRect.width();
textHeight += (tvRect.height() + 10);
}
}
postInvalidate();
}
/**
-
同步设置水印文字内容
-
@param text 文字内容
*/
void setSyncText(String… text) {
if (mSync) {
setText(text);
}
}
/**
-
设置水印倾斜角度
-
@param degrees 倾斜角度(默认:-30)
*/
public void setDegrees(int degrees) {
mDegrees = degrees;
postInvalidate();
}
/**
-
同步设置水印倾斜角度
-
@param degrees 倾斜角度(默认:-30)
*/
void setSyncDegrees(int degrees) {
if (mSync) {
setDegrees(degrees);
}
}
/**
-
设置水印字体颜色
-
@param textColor 字体颜色(默认:#33000000)
*/
public void setTextColor(int textColor) {
mTextColor = textColor;
mTextPaint.setColor(mTextColor);
postInvalidate();
}
/**
-
同步设置水印字体颜色
-
@param textColor 字体颜色(默认:#33000000)
*/
void setSyncTextColor(int textColor) {
if (mSync) {
setTextColor(textColor);
}
}
/**
-
设置水印字体大小(单位:px)
-
@param textSize 字体大小(默认:42px)
*/
public void setTextSize(int textSize) {
mTextSize = textSize;
mTextPaint.setTextSize(30);
postInvalidate();
}
/**
-
同步设置水印字体大小(单位:px)
-
@param textSize 字体大小(默认:42px)
*/
void setSyncTextSize(int textSize) {
if (mSync) {
setTextSize(30);
}
}
/**
-
设置水印字体是否粗体
-
@param textBold 是否粗体(默认:false)
*/
public void setTextBold(boolean textBold) {
mTextBold = textBold;
mTextPaint.setTypeface(mTextBold ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
postInvalidate();
}
/**
-
同步设置水印字体是否粗体
-
@param textBold 是否粗体(默认:false)
*/
void setSyncTextBold(boolean textBold) {
if (mSync) {
setTextBold(textBold);
}
}
/**
-
设置水印X轴偏移量(单位:px)
-
@param dx X轴偏移量(默认:100px)
*/
public void setDx(int dx) {
this.mDx = dx;
postInvalidate();
}
/**
-
同步设置水印X轴偏移量(单位:px)
-
@param dx X轴偏移量(默认:100px)
*/
void setSyncDx(int dx) {
if (mSync) {
setDx(dx);
}
}
/**
-
设置水印Y轴偏移量(单位:px)
-
@param dy Y轴偏移量(默认:240px)
*/
public void setDy(int dy) {
this.mDy = dy;
postInvalidate();
}
/**
-
同步设置水印Y轴偏移量(单位:px)
-
@param dy Y轴偏移量(默认:240px)
*/
void setSignDy(int dy) {
if (mSync) {
setDy(dy);
}
}
/**
-
设置水印对齐方式
-
@param align 对齐方式(默认:Center)
*/
public void setAlign(Paint.Align align) {
this.mAlign = align;
postInvalidate();
}
/**
-
同步设置水印对齐方式
-
@param align 对齐方式(默认:Center)
*/
void setSignAlign(Paint.Align align) {
if (mSync) {
setAlign(align);
}
}
/**
- 销毁相关页面时调用(切记)
*/
public void onDestroy() {
if (mSync) {
WaterMarkManager.LIST.remove(this);
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return false;
}
@SuppressLint(“ClickableViewAccessibility”)
@Override
public boolean onTouchEvent(MotionEvent event) {
return false;
}
}
package com.hkdc.commonlib.warkmark;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Paint;
import android.view.LayoutInflater;
import com.hkdc.commonlib.R;
import java.util.ArrayList;
import java.util.List;
/**
-
@author Leon (wshk729@163.com)
-
@date 2018/8/24
-
*/
public class WaterMarkManager {
static WaterMarkInfo INFO = null;
static String[] CONTENT = null;
static List LIST = new ArrayList<>();
/**
-
设置水印全局配置信息
-
@param info 配置信息
*/
public static void setInfo(WaterMarkInfo info) {
INFO = info;
}
/**
-
获取一个满屏水印View
-
@param activity activity
*/
@SuppressLint(“InflateParams”)
public static WaterMarkView getView(Activity activity) {
return (WaterMarkView) LayoutInflater.from(activity).inflate(R.layout.view_water_mark, null);
}
/**
- WaterMarkInfo初始化判断
*/
private static void assertInitialized() {
if (INFO == null) {
INFO = WaterMarkInfo.create().generate();
}
}
/**
-
同步设置全部水印文字信息
-
@param content 文字信息
*/
public static void setText(String… content) {
assertInitialized();
CONTENT = content;
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncText(content);
}
}
}
}
/**
-
同步设置全部水印倾斜角度
-
@param degrees 倾斜角度(默认:-30)
*/
public static void setDegrees(int degrees) {
assertInitialized();
INFO.setDegrees(degrees);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncDegrees(degrees);
}
}
}
}
/**
-
同步设置全部水印字体颜色
-
@param textColor 字体颜色(默认:#33000000)
*/
public static void setTextColor(int textColor) {
assertInitialized();
INFO.setTextColor(textColor);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncTextColor(textColor);
}
}
}
}
/**
-
同步设置全部水印字体大小(单位:px)
-
@param textSize 字体大小(默认:42px)
*/
public static void setTextSize(int textSize) {
assertInitialized();
INFO.setTextSize(textSize);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncTextSize(textSize);
}
}
}
}
/**
-
同步设置全部水印字体是否粗体
-
@param textBold 是否粗体(默认:false)
*/
public static void setTextBold(boolean textBold) {
assertInitialized();
INFO.setTextBold(textBold);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncTextBold(textBold);
}
}
}
}
/**
-
同步设置全部水印X轴偏移量(单位:px)
-
@param dx X轴偏移量(默认:100px)
*/
public static void setDx(int dx) {
assertInitialized();
INFO.setDx(dx);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSyncDx(dx);
}
}
}
}
/**
-
同步设置全部水印Y轴偏移量(单位:px)
-
@param dy Y轴偏移量(默认:240px)
*/
public static void setDy(int dy) {
assertInitialized();
INFO.setDy(dy);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSignDy(dy);
}
}
}
}
/**
-
同步设置全部水印对齐方式
-
@param align 对齐方式(默认:Center)
*/
public static void setAlign(Paint.Align align) {
assertInitialized();
INFO.setAlign(align);
if (LIST.size() > 0) {
for (WaterMarkView view : LIST) {
if (view != null) {
view.setSignAlign(align);
}
}
}
}
}
view_water_mark.xml
<?xml version="1.0" encoding="utf-8"?><com.commonlib.WaterMarkView
xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent”
android:layout_height=“match_parent”/>
import android.graphics.Color;
import android.graphics.Paint;
/**
-
@author Leon (wshk729@163.com)
-
@date 2018/8/24
-
*/
public class WaterMarkInfo {
private int mDegrees;
private int mTextColor;
private int mTextSize;
private boolean mTextBold;
private int mDx;
private int mDy;
private Paint.Align mAlign;
private WaterMarkInfo(int degrees, int textColor, int textSize, boolean textBold, int dx, int dy, Paint.Align align) {
mDegrees = degrees;
mTextColor = textColor;
mTextSize = textSize;
mTextBold = textBold;
mDx = dx;
mDy = dy;
mAlign = align;
}
public int getDegrees() {
return mDegrees;
}
public int getTextColor() {
return mTextColor;
}
public int getTextSize() {
return mTextSize;
}
public int getDx() {
return mDx;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
写在最后
本次我的分享也接近尾声了,感谢你们在百忙中花上一下午来这里聆听我的宣讲,希望在接下来的日子,我们共同成长,一起进步!!!
最后放上一个大概的Android学习方向及思路(详细的内容太多了~),提供给大家:
对于程序员来说,要学习的知识内容、技术有太多太多,这里就先放上一部分,其他的内容有机会在后面的文章向大家呈现出来,不过我自己所有的学习资料都整理成了一个文档,一直在不断学习,希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!
Android架构师之路很漫长,一起共勉吧!
如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
技术停滞不前!**
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-IpJtTDm8-1712156552756)]
[外链图片转存中…(img-XknZb1an-1712156552757)]
[外链图片转存中…(img-7C3UMUls-1712156552757)]
[外链图片转存中…(img-iTtMk9E1-1712156552758)]
[外链图片转存中…(img-KpwmRzyI-1712156552758)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
写在最后
本次我的分享也接近尾声了,感谢你们在百忙中花上一下午来这里聆听我的宣讲,希望在接下来的日子,我们共同成长,一起进步!!!
最后放上一个大概的Android学习方向及思路(详细的内容太多了~),提供给大家:
[外链图片转存中…(img-Xqp1UblY-1712156552758)]
对于程序员来说,要学习的知识内容、技术有太多太多,这里就先放上一部分,其他的内容有机会在后面的文章向大家呈现出来,不过我自己所有的学习资料都整理成了一个文档,一直在不断学习,希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!
Android架构师之路很漫长,一起共勉吧!
如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。
[外链图片转存中…(img-bomFPhXv-1712156552759)]