如何在Android中使用StaticLayout?
我需要构建自己的自定义如何在Android中使用StaticLayout?,android,canvas,text,android-custom-view,staticlayout,Android,Canvas,Text,Android Custom View,Staticlayout,我需要构建自己的自定义TextView,因此我一直在学习如何在画布上绘制文本。这比直接使用Canvas.drawText()更可取,或者像上面所说的那样。但是,文档中没有给出如何实现的示例。只有一个模糊的说法是作为一种新的方式来做这件事 我找到了一个例子,但它似乎有点过时 我终于想出了如何做到这一点,所以我在下面添加了我的解释。StaticLayout()用于在画布上布局和绘制文本。它通常用于以下任务: 测量布局后多行文字的大小 在位图图像上绘制文本 创建一个处理自己的文本布局的自定义视图(与
TextView
,因此我一直在学习如何在画布上绘制文本。这比直接使用Canvas.drawText()
更可取,或者像上面所说的那样。但是,文档中没有给出如何实现的示例。只有一个模糊的说法是作为一种新的方式来做这件事
我找到了一个例子,但它似乎有点过时
我终于想出了如何做到这一点,所以我在下面添加了我的解释。StaticLayout
()用于在画布上布局和绘制文本。它通常用于以下任务:
- 测量布局后多行文字的大小
- 在位图图像上绘制文本
- 创建一个处理自己的文本布局的自定义视图(与使用嵌入的
创建复合视图相反)<代码>文本视图本身使用的是TextView
李>静态布局
Paint
或TextPaint
测量
String text = "This is some text."
TextPaint myTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
mTextPaint.setColor(0xFF000000);
float width = mTextPaint.measureText(text);
float height = -mTextPaint.ascent() + mTextPaint.descent();
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);
int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);
float height = myStaticLayout.getHeight();
多行
但是,如果有换行并且需要高度,那么最好使用静态布局
。您可以提供宽度,然后从StaticLayout
获取高度
String text = "This is some text."
TextPaint myTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
mTextPaint.setColor(0xFF000000);
float width = mTextPaint.measureText(text);
float height = -mTextPaint.ascent() + mTextPaint.descent();
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);
int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);
float height = myStaticLayout.getHeight();
新API
如果您想使用较新版本(可从API 23获得),您可以获得如下布局:
StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(), myTextPaint, width);
StaticLayout myStaticLayout = builder.build();
您可以使用点符号添加设置:
StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0, text.length(), myTextPaint, width)
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setLineSpacing(spacingAddition, spacingMultiplier)
.setIncludePad(includePadding)
.setMaxLines(5);
StaticLayout myStaticLayout = builder.build();
在图像上写入文本
以后我可能会对此进行更多的扩展,但现在请参见一个使用StaticLayout
并返回位图的方法示例
创建自定义文本处理视图
下面是一个使用StaticLayout
的自定义视图示例。它的行为类似于一个简单的文本视图
。当文本太长而无法在屏幕上显示时,它会自动换行并增加其高度
代码
MyView.java
activity_main.xml
注释
- ,并有助于学习如何创建自定义文本处理视图
- 查看是否要添加可从代码或xml设置的自定义属性
- 以下是我对在画布上绘制多行文本的解释
声明绘制对象。使用TextPaint,它是Paint的扩展
TextPaint textPaint;
初始化绘制对象。设置自己的颜色、尺寸等
textPaint = new TextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
textPaint.setColor(Color.YELLOW);
添加getTextHeight函数
private float getTextHeight(String text, Paint paint) {
Rect rect = new Rect();
paint.getTextBounds(text, 0, text.length(), rect);
return rect.height();
}
在onDraw函数中,输入如下行
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
String text = "This is a lengthy text. We have to render this properly. If layout mess users review will mess. Is that so ? ";
Rect bounds = canvas.getClipBounds();
StaticLayout sl = new StaticLayout(text, textPaint, bounds.width(),
Layout.Alignment.ALIGN_CENTER, 1, 1, true);
canvas.save();
//calculate X and Y coordinates - In this case we want to draw the text in the
//center of canvas so we calculate
//text height and number of lines to move Y coordinate to center.
float textHeight = getTextHeight(text, textPaint);
int numberOfTextLines = sl.getLineCount();
float textYCoordinate = bounds.exactCenterY() -
((numberOfTextLines * textHeight) / 2);
//text will be drawn from left
float textXCoordinate = bounds.left;
canvas.translate(textXCoordinate, textYCoordinate);
//draws static layout on canvas
sl.draw(canvas);
canvas.restore();
}
礼节转到您必须在StaticLayout的构造函数/获取方法中传递text.length()-1,否则您将获得IndexOutOfBoundException