Android自定义View系列

  • Android自定义View注意事项
  • Android自定义View之图像的色彩处理
  • Android自定义View之Canvas
  • Android自定义View之轻松实现圆角和圆形图片
  • Android自定义View之双缓冲机制和SurfaceView
  • Android自定义View之Window、ViewRootImpl和View的三大流程
  • Android自定义View之事件分发机制总结
  • Android自定义View之requestLayout方法和invalidate方法

用继承View的方式来自定义View,我们就需要重写onDraw方法,也就是得咱自己来画图了。画图就得用到画笔和画布,也就是Paint和Canvas。我们先来了解下Paint。

Paint

Paint我们可以简单理解为画笔或是PS里的油漆桶,也就是实际上需要设置比如颜色、粗细、字体大小等属性的对象。我们在通过继承View来自定义View时,就是通过设置Paint的属性来控制我们画出来的View的一些特性。

Paint的一些常见API

1.设置文字的对齐方式:setTextAlign()

//设置Paint的文字对齐方式
textPaint = new Paint();
textPaint.setTextAlign(Paint.Align.RIGHT);
...@Override
public void onDraw(Canvas canvas) {super.onDraw(canvas);Log.e(TAG, "onDraw");//文字的起点为(getWidth()/2,getHeight()/2)canvas.drawText(text, getWidth()/2,getHeight()/2,textPaint);
}

对齐方式有左中右三种

//对齐方式有左中右三种
public enum Align {/*** The text is drawn to the right of the x,y origin*/LEFT    (0),/*** The text is drawn centered horizontally on the x,y origin*/CENTER  (1),/*** The text is drawn to the left of the x,y origin*/RIGHT   (2);private Align(int nativeInt) {this.nativeInt = nativeInt;}final int nativeInt;
}

需要注意的是,这里的对齐方式指的是和绘制原点的对齐方式,也就是上面canvas.drawText方法中我们设置的绘制起点。比如我们设置的是右对齐,那就是文字的右边和绘制起点对齐,具体效果可以看图

2.设置Paint的颜色、字体大小和字体

//这里设置Paint的颜色后,如果绘制的是字体那就是字体颜色,如果绘制的线条,那就是线条的颜色
textPaint.setColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
textPaint.setTextSize(80f);
//设置字体加粗
textPaint.setTypeface(Typeface.DEFAULT_BOLD);

字体样式有很多,除了常见的加粗,还有斜体等。这些都在Typeface类中

public class Typeface {//字体样式,除了加粗,其他的好像看不出多大的区别public static final Typeface DEFAULT_BOLD;/** The NORMAL style of the default sans serif typeface. */public static final Typeface SANS_SERIF;/** The NORMAL style of the default serif typeface. */public static final Typeface SERIF;/** The NORMAL style of the default monospace typeface. */public static final Typeface MONOSPACE;// Stylepublic static final int NORMAL = 0;//加粗public static final int BOLD = 1;//倾斜public static final int ITALIC = 2;//加粗并倾斜public static final int BOLD_ITALIC = 3;
}

设置加粗、倾斜

Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC);
textPaint.setTypeface(font);

Typeface类还提供了加载自定义字体的API

//从assets资源中加载
Typeface createFromAsset(AssetManager mgr, String path)
//从文件中加载字体
Typeface createFromFile(String path)
public static Typeface createFromFile(File path)

3.设置Paint的style

textPaint.setStyle(Paint.Style.FILL);

style有3种,分别为实心、空心和实心描边。

public enum Style {//实心FILL            (0),//空心STROKE          (1),//实心描边FILL_AND_STROKE (2);Style(int nativeInt) {this.nativeInt = nativeInt;}final int nativeInt;
}

测试发现对文字和线都会有影响,比如如果我们设置了文字的下划线,那FILL就是实线,而设置STROKE就会变成空心的一条线。如果我们是画一个矩形的话,那FILL就是实心的矩形,而STROKE就是一个矩形框,FILL_AND_STROKE效果大家可以试一下。文字的话STROKE就是文字的笔画中间是空的,Fill就是实心的。

4.设置缩放:setTextScaleX(float scaleX)。scaleX范围在0-1之间为缩小,大于1为放大

5.设置下划线和删除线有2种方式,一种是直接调用Paint的API,一种是直接设置Paint的Flag

1) 直接通过Paint的API设置文字的下划线和删除线

//设置下划线
textPaint.setUnderlineText(true);
//设置文字中间的删除线
textPaint.setStrikeThruText(true);

2) 用设置Paint的Flag的方式设置文字的下划线和删除线

设置下划线
textPaint.setFlags(Paint.UNDERLINE_TEXT_FLAG);
//设置文字中间的删除线
textPaint.setFlags(Paint.STRIKE_THRU_TEXT_FLAG);

需要注意的是Paint的Flag相互之间是冲突的,如果设置了多个Flag,那只有最后一个Flag会生效。像上面的例子中,通过Flag来设置文字的下划线和删除线,最后只有删除线会生效。而通过Paint的API就不会有这个问题,删除线和下划线都会同时生效。

6.设置Paint的抗锯齿Flag。一般我们都要设置这个抗锯齿效果,否则画出来的线和文字会坑坑洼洼的,设置了以后就会很平滑。

//通过设置Flag来应用抗锯齿效果
textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);//通过Paint的API来设置抗锯齿效果
textPaint.setAntiAlias(true);

这里也就引申出一个问题:那就是我们一搬都会设置Paint的Flag为抗锯齿效果,所以如果我们要设置文字的下划线和删除线,就只能通过Paint的API来设置了。

文字居中的问题

不知道大家发现没有,上面图片中的文字尽管绘制的时候设置的位置是 (getWidth()/2,getHeight()/2) 但实际效果却并没有居中

(1)水平方向居中问题

  • 水平方向没有居中是因为文字本身有宽度,所以要先获取文字的宽度
float textWidth = textPaint2.measureText(text);
  • 然后重新计算绘制的水平坐标
canvas.drawText(text, (getWidth()-textWidth)/2,getHeight()/2,textPaint2);

(2)竖直方向居中问题

文字的绘制规则跟Paint的一个内部类有关:FontMetrics

public static class FontMetrics {/*** The maximum distance above the baseline for the tallest glyph in* the font at a given text size.*/public float   top;/*** The recommended distance above the baseline for singled spaced text.*/public float   ascent;/*** The recommended distance below the baseline for singled spaced text.*/public float   descent;/*** The maximum distance below the baseline for the lowest glyph in* the font at a given text size.*/public float   bottom;/*** The recommended additional space to add between lines of text.*/public float   leading;
}

从图中我们可以看出,文字绘制以baseline为标准,我们将baseline设置为getHeight()/2后,文字势必会往上偏,所以我们要想让文字在竖直方向上居中,baseline需要往下一点。

Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float y = getHeight()/2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent)/2;
canvas.drawText(text, (getWidth()-textWidth)/2,y,textPaint);

需要注意的是Paint的TextAlign属性需要去掉

这样子文字就居中了

用Paint绘制线

PathEffect setPathEffect(PathEffect effect)

1)通过setPathEffect方法可以设置路径效果,一共可以设置7种路径效果,比较常见的有虚线和拐角圆滑效果

//CornerPathEffect用于增加点与点之间的圆弧效果,CornerPathEffect中的参数表示圆弧效果的半径
brokenLinePaint.setPathEffect(new CornerPathEffect(5));
//DashPathEffect用于绘制虚线,第一个参数表示线段各个点之间的偏移,第二个参数表示绘制时数组的偏移量
brokenLinePaint.setPathEffect(new DashPathEffect(new float[]{5f,5f,5f,5f}, 1f));

需要注意的是Paint的PathEffect也只能设置一个,设置多个时只有最后一个设置有效

2)Paint绘制折线需要用到一个Path类,用于存放折线的各个点

1)初始化

Path mPath = new Path();

2)设置折线的起点

//2个参数分别为起点的X坐标和Y坐标
mPath.moveTo(mPaddingLeft, mHeight-mPaddingBottom);

3)添加折线上的其他点

 mPath.lineTo(pointX, pointy);

4)绘制

canvas.drawPath(mPath, brokenLinePaint);

总结

  • Paint是绘制View必须要掌握的,我们只需要掌握Paint的常见的API就行了,包括绘制文字的和绘制线的。
  • Paint绘制文字时需要注意文字居中的问题,水平居中需要考虑文字的宽度,竖直居中需要考虑文字绘制的baseline,这就需要注意理解FontMetrics,如果不理解的话直接记结论也行
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float y = getHeight()/2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent)/2;
canvas.drawText(text, (getWidth()-textWidth)/2,y,textPaint);
  • Paint的Flag只能设置一个,设置多个时也只有最后一个有效。
  • Paint的PathEffect和Flag也一样,只能设置一个,设置多个时只有最后一个有效


欢迎关注我的微信公众号,查看更多精彩文章,和我一起每天进步一点点!

Android自定义View之Paint绘制文字和线相关推荐

  1. 精通Android自定义View(十四)绘制水平向右加载的进度条

    1引言 1 精通Android自定义View(一)View的绘制流程简述 2 精通Android自定义View(二)View绘制三部曲 3 精通Android自定义View(三)View绘制三部曲综合 ...

  2. 精通Android自定义View(十二)绘制圆形进度条

    1 绘图基础简析 1 精通Android自定义View(一)View的绘制流程简述 2 精通Android自定义View(二)View绘制三部曲 3 精通Android自定义View(三)View绘制 ...

  3. android多行文字正中间显示,Android自定义View五(绘制文本大小、多行多列居中)...

    一.绘制文本 在Canvas中绘制文本,使用前面文章的坐标系 1.drawText的几种方法 public void drawText (String text, float x, float y, ...

  4. android自定义虚线,Android自定义view的方式绘制虚线

    Android自定义view绘制虚线 最近项目中有个需求,通过自定义view的方式绘制虚线 别的不多说先看一眼效果 这个需求在我们的开发中应该是一个很常见的需求了吧,有人会说有更简单的实现方式,对,但 ...

  5. Android自定义View之Canvas绘制基本图形(二)-- 自定义时钟

    前言 前面一篇主要是巩固Cavas绘制基本图形(如直线,矩形,点等等),今天同样是复习Cavas画圆,圆弧,等等,但是今天会多了一个path,以及Canvas画布的旋转.缩放.平移等等,画布的保存(s ...

  6. 【Android 自定义 View】--> 绘制时钟(表)效果

    前言 本篇文章主要介绍使用自定义 View 来实现时钟效果,灵活地使用 Android 的 Canvas,Paint, Path 的 API 以及理清 Canvas 的 save 和 restore ...

  7. android 自定义paint,Android自定义View中Paint、Rect、Canvas介绍(一)

    自定义View对于新手而言貌似是一个很复杂的东西.格式,各函数的意义.对于大神经常忘记各函数及一些参数的具体写法及意义,刚好在做一个风车效果,把过程及遇到的问题都写下来 1.如何自定义一个View p ...

  8. android 自定义多边形,Android:自定义view之Canvas绘制图形

    前面讲解了onMeasure,接下来讲解onDraw,onDraw主要就是绘制,也就是我们真正关心的部分,使用的是Canvas绘图. @Override protected void onDraw(C ...

  9. Android自定义View之paint(一)

    2019独角兽企业重金招聘Python工程师标准>>> 学习自定义view,就是将view绘成自己想要的样子,自然就要有绘画的工具,那就是Paint. **1. 构造函数 ** Pa ...

最新文章

  1. [JAVA EE]session 和 token 机制
  2. Angular vs React 最全面深入对比
  3. 从JSON数据中取出相关数据
  4. ubuntu下连接mysql出现Access denied for user ‘rose‘@‘localhost‘ (using password: NO)的解决方法
  5. python搞笑代码-【转】 Python 程序员的进化--搞笑版
  6. vim配置及插件安装管理
  7. linux软件抗干扰,解决asterisk下使用misdn时被SELinux干扰导致权限不足的问题
  8. 31 GroupSock(AddressString)——live555源码阅读(四)网络
  9. 信道估计之LMMSE估计
  10. uniapp app端登录
  11. MATLAB基础语法之蒙特卡罗模拟_1(布丰投针)
  12. 千千静听V5.6 Beta3 美化增强版
  13. 艾盟赢销浅谈:CRM的本质和它的未来十年
  14. linux中进程unit是什么意思,linux---systemd进程
  15. 1、基于51单片机智能水杯系统设计
  16. css案例2——黑白滤镜
  17. oracle sqlnet配置,sqlnet.ora文件配置详解
  18. Flutter自定义背景色渐变 按钮 组件
  19. 玄武密码(bzoj4327)(JSOI2012)
  20. 大数据给人们生活带来的改变_大数据时代,对人们生活的影响在哪些方面

热门文章

  1. 短网址有哪些应用场景,为什么要缩短网址
  2. 应用网站微信扫码登录处理逻辑解析
  3. 聊聊IM系统的即时性和可靠性
  4. 如何将Nintendo Switch Joy-Con或Pro控制器连接到PC
  5. layui使用富文本已经使用第三方插件Kz.layedit来优化layui的富文本
  6. 松下FP XH六轴标准程序,程序控制六个伺服,轴的点动控制
  7. Microsoft Office下载连接office2013-2016-2019-2021-365下载链接
  8. PogoPlug安装迷你云
  9. 【研究院】一年了,再看看江湖中的达摩院
  10. 智能cv5200模块方案,无线远距离WiFi传输,无线通信技术应用