转载请注明出处: http://www.cnblogs.com/renhui/p/7453534.html

这里的绘制文字不是直接调用TextView.setText(String content)去展示文字内容。而是在View上面通过 canvas.drawText(text, x, y,textPaint) 的方式直接进行文字的绘制。

一、基本的文字绘制方式

canvas.drawText的方式,需要我们计算好要绘制的文字的起始位置,并通过移动画布的来移动到指定的位置,绘制文字完成后然后再复原画布的位置。

canvas.translate(x, y); // 挪动canvas的坐标原点
canvas.drawText(text, x, y, tp);
canvas.translate(-x, -y); // 恢复canvas的坐标原点

通过这段代码,就可以将文字绘制在指定的位置。

但是有时候我们发现,如果需要绘制的内容很多的时候,直接使用 canvas.drawText 存在很大的问题,列举其中几个问题如下:

  • 只能在一行进行绘制,不会自动换行。
  • 即使内容里面存在'\n'等换行字符,可是绘制出来的文字还是在一行里面,'\n'字符展示出来的效果仅仅是一个空格。
  • 超出屏幕的内容是看不到的。

那么怎么处理这个问题呢?Android 的API 里面 有一个非常棒的工具类 -- StaticLayout。通过StaticLayout,我们就能够实现了文本绘制换行处理

二、使用StaticLayout绘制文本

public void onDraw(Canvas canvas){
  super.onDraw(canvas);
  TextPaint tp = new TextPaint();
  tp.setColor(Color.BLUE);
  tp.setStyle(Style.FILL);
  tp.setTextSize(50);
  String message = "8月30日中午,法制晚报·看法新闻记者从中国电信、中国联通、中国移动获悉,三大运营商将从9月1日起全面取消手机国内长途费和漫游费(不含港澳台,下同),比原计划的10月1日提前一个月完成。用户无需申请,自动生效。";
  StaticLayout myStaticLayout = new StaticLayout(message, tp, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
  myStaticLayout.draw(canvas);
  canvas.restore();
}

上面这段代码就是使用StaticLayout绘制文本的基本使用方式。运行后发现跟TextView的效果是一样的,通过阅读android源码可以发现,其实TextView也是调用StaticLayout来实现换行的。

StaticLayout的构造函数有三个:

public StaticLayout(CharSequence source, // 需要分行的字符串
TextPaint paint, // 画笔对象
int width, // layout的宽度,字符串超出宽度时自动换行
Layout.Alignment align, // 对齐方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三种
float spacingmult, // 相对行间距,相对字体大小,1.5f表示行间距为1.5倍的字体高度。
float spacingadd, // 在基础行距上添加多少(实际行间距等于两者和)
boolean includepad)
public StaticLayout(CharSequence source, // 需要分行的字符串
int bufstart, // 需要分行的字符串从第几位开始
int bufend, // 需要分行的字符串到哪里结束
TextPaint paint, // 画笔对象
int outerwidth, // layout的宽度,字符串超出宽度时自动换行
Layout.Alignment align, // 对齐方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三种
float spacingmult, // 相对行间距,相对字体大小,1.5f表示行间距为1.5倍的字体高度。
float spacingadd, // 在基础行距上添加多少
boolean includepad)
public StaticLayout(CharSequence source, // 需要分行的字符串
int bufstart, // 需要分行的字符串从第几位开始
int bufend, // 需要分行的字符串到哪里结束
TextPaint paint, // 画笔对象
int outerwidth, // layout的宽度,字符串超出宽度时自动换行。
Layout.Alignment align, // 对齐方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三种。
float spacingmult, // 相对行间距,相对字体大小,1.5f表示行间距为1.5倍的字体高度。
float spacingadd, // 在基础行距上添加多少
boolean includepad,
TextUtils.TruncateAt ellipsize,
int ellipsizedWidth)

三、使用StaticLayout的情景

我们已经知道,使用StaticLayout可以很好的帮助我们处理文字绘制时的换行问题,那么什么地方我们能够用到StaticLayout呢?下面我可以列举几个例子:

1. 辅助图文混排的编辑器,生成图文一体的长图 -- 需要自定义View绘制的基础。

2. 音乐播放器类,桌面歌词滚动(可带颜色)

Android 使用View绘制文字(DrawText)技术总结的更多相关文章

  1. Android 自定义 View 绘制

    在 Android 自定义View 里面,介绍了自定义的View的基本概念.同时在 Android 控件架构及View.ViewGroup的测量 里面介绍了 Android 的坐标系 View.Vie ...

  2. android自定义View绘制天气温度曲线

    原文:android自定义View绘制天气温度曲线 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012942410/article/detail ...

  3. Android之View绘制流程源码分析

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 对于稍有自定义View经验的安卓开发者来说,onMeasure,onLayout,onDraw这三个方法都不会陌生,起码多少都有所接触吧. 在安卓中 ...

  4. Android笔记--View绘制流程源码分析(二)

    Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...

  5. Android笔记--View绘制流程源码分析(一)

    Android笔记--View绘制流程源码分析 View绘制之前框架流程分析 View绘制的分析始终是离不开Activity及其内部的Window的.在Activity的源码启动流程中,一并包含 着A ...

  6. Android中View绘制流程以及invalidate()等相关方法分析

    [原文]http://blog.csdn.net/qinjuning 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简 ...

  7. Android中View绘制流程以及invalidate()等相关方法分析(转载的文章,出处在正文已表明)

    转载请注明出处:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时 ...

  8. android之View绘制

    Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类,由此就得到了视图部分的基本结构--树形结构 View定义了绘图的基本 ...

  9. Android中View绘制流程以及invalidate()等相关方法分析(转)

    转自:http://blog.csdn.net/qinjuning 前言: 本文是我读<Android内核剖析>第13章----View工作原理总结而成的,在此膜拜下作者 .同时真挚地向渴 ...

随机推荐

  1. WPF程序 双击exe自动申请“以管理员方式运行”权限

    实现方式: 在 xxx.exe 目录下包含其对应的清单文件(xxx.exe.manifest, 由 VS 编译时自动生成): 用记事本打开 manifest 文件,将文件中的项:<request ...

  2. ffmpeg使用经验

    1.工作要使用ffmpeg将视频转换成H264格式,网上查到的很多使用方法都是如下: ffmpeg -i input.mov -c:v libx264 -crf output.mov -i后面表示输入 ...

  3. Linux命令:readonly

    readonly [-aAf] [name[=value] ...] or readonly -p -A 表示后面的name变量都是关联数组 -a 表示后面的name变量都是index数组 -f 表示 ...

  4. MYSQL性能优化(2)

    Insert语句优化 1.  多行并为一个语句  insert into table values (行1),(行2),........... 2. 使用中间内存队列, 逻辑是立马执行插入,其他数据放 ...

  5. asp.net文件/大文件上传需要配置的项目整理

    HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 最可能的原因: •Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值. 可尝 ...

  6. ubuntu环境下,ubuntu16.04装机到nvdia显卡驱动安装、cuda8安装、cudnn安装

    首先是安装ubuntu16.04 A.制作u盘启动盘(提前准备好.ios文件): 1.安装u盘制作工具unetbootinsudo apt-get install unetbootin2.格式化u盘s ...

  7. NYOJ252-01串-(数位dp)

    252-01串 内存限制:64MB 时间限制:1000ms 特判: No通过数:33 提交数:49 难度:2 题目描述: ACM的zyc在研究01串,他知道某一01串的长度,但他想知道不含有“11”子 ...

  8. ie7ajax 跨域 no transport 解决办法

    客户端js <script src="jquery-1.8.0.min.js"></script> <script src="JavaScr ...

  9. 云笔记项目-AOP知识简单学习

    在云笔记项目的过程中,需要检查各个业务层的执行快慢,如登录.注册.展示笔记本列表,展示笔记列表等,如果在每个业务层方法里都写一段代码用来检查时间并打印,不仅仅显得代码重复,而且当项目很大的时候,将大大 ...

  10. mysql学习笔记--列属性

    一.是否为空----null || not null 二.默认值----default 三.自动增长----auto_increment 四.主键----primary key 1. 主键:唯一标识表 ...