请谈谈源码中StaticLayout的用法和应用场景?
更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅
什么是StaticLayout?
StaticLayout
是Android中处理多行文本测量与布局的核心类,专门用于在自定义View或Canvas上绘制复杂文本。与DynamicLayout
不同,它适用于静态文本场景(文本内容不变),通过预计算文本分行和测量结果提升绘制性能。
核心构造方法参数详解
public StaticLayout(CharSequence source, // 需要分行的原始文本int bufstart, // 文本起始索引(通常为0)int bufend, // 文本结束索引(source.length())TextPaint paint, // 控制文本样式的画笔(颜色/字号/字体等)int outerwidth, // 布局宽度(超出此宽度自动换行)Alignment align, // 对齐方式(NORMAL左对齐/CENTER居中/OPPOSITE右对齐)float spacingmult, // 行间距倍数(1.0为默认行高,1.5=1.5倍行高)float spacingadd, // 行间距附加值(像素单位,在倍数基础上追加)boolean includepad, // 是否包含额外行间距(解决首行顶部空隙问题)TextUtils.TruncateAt ellipsize, // 省略号位置(START/MIDDLE/END)int ellipsizedWidth // 触发省略的宽度阈值
)
关键应用场景
-
自定义文本绘制
在View.onDraw()
中直接绘制多行文本:@Override protected void onDraw(Canvas canvas) {TextPaint textPaint = new TextPaint();textPaint.setColor(Color.BLACK);textPaint.setTextSize(48);StaticLayout layout = new StaticLayout("这是一段需要自动换行的长文本".repeat(10),textPaint,getWidth(),Layout.Alignment.ALIGN_NORMAL,1.2f, // 行间距1.2倍0,true);canvas.save();layout.draw(canvas); // 自动处理换行和绘制canvas.restore(); }
-
复杂文本布局
- 实现图文混排(文本环绕图片)
- 聊天气泡中的多行文本测量
- 阅读类App的分页计算
-
性能敏感场景
当文本内容固定时,通过预创建StaticLayout避免重复计算:// 在初始化时创建(非绘制流程中) private StaticLayout cachedLayout;void initLayout() {cachedLayout = new StaticLayout(...); }void onDraw(Canvas canvas) {cachedLayout.draw(canvas); // 直接复用 }
实战技巧
-
省略号优化
结合ellipsize
和ellipsizedWidth
实现文本截断:new StaticLayout(text,paint,maxWidth,Alignment.ALIGN_NORMAL,1.0f,0,true,TextUtils.TruncateAt.END, // 末尾加省略号maxWidth );
-
行高精确控制
通过spacingmult
和spacingadd
组合调节:// 行高 = 字体高度 * 1.5 + 10px float spacingMulti = 1.5f; float spacingAdd = 10;
-
首行顶部对齐
设置includepad=true
消除首行上方空白:- | 默认会有顶部留白 | + |文本直接顶格显示|
性能对比
方案 | 适用场景 | 性能开销 |
---|---|---|
StaticLayout | 静态文本/预计算 | ⭐⭐ |
DynamicLayout | 可编辑文本(如EditText) | ⭐⭐⭐⭐ |
手动Canvas.drawText | 单行简单文本 | ⭐ |
提示:在Android 8.0+建议使用
StaticLayout.Builder
构建,但核心参数逻辑不变。