我需要构建自己的自定义,TextView
所以我一直在学习StaticLayout
在画布上绘制文本.这比Canvas.drawText()
直接使用更好,或者说文档说的.但是,文档没有给出任何示例.只有模糊的参考才能StaticLayout.Builder
成为更新的方法.
我在这里找到了一个例子,但似乎有点过时了.
我终于工作了,但是我在下面添加了我的解释.
StaticLayout
(类似于DynamicLayout
和BoringLayout
)用于在画布上布局和绘制文本.它通常用于以下任务:
测量布局后多行文字的大小.
在位图图像上绘制文本.
创建一个处理自己的文本布局的自定义视图(而不是使用嵌入式创建复合视图TextView
).TextView
本身使用StaticLayout
内部.
测量文字大小
单线
如果您只有一行文字,可以用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();
多行
但是,如果有换行并且你需要高度,那么最好使用a StaticLayout
.你提供宽度,然后你可以从中获得高度StaticLayout
.
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
如果您想使用较新的StaticLayout.Builder
(可从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(spacingMultiplier, spacingAddition) .setIncludePad(includePadding) .setMaxLines(5); StaticLayout myStaticLayout = builder.build();在图像上写文字
我可能会在将来扩展它,但是现在看一下这个帖子的一个使用StaticLayout
和返回位图的方法的例子.
以下是使用a的自定义视图的示例StaticLayout
.它表现得像一个简单的TextView
.当文本太长而无法放在屏幕上时,它会自动换行并增加其高度.
码
MyView.java
public class MyView extends View { String mText = "This is some text."; TextPaint mTextPaint; StaticLayout mStaticLayout; // use this constructor if creating MyView programmatically public MyView(Context context) { super(context); initLabelView(); } // this constructor is used when created from xml public MyView(Context context, AttributeSet attrs) { super(context, attrs); initLabelView(); } private void initLabelView() { mTextPaint = new TextPaint(); mTextPaint.setAntiAlias(true); mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density); mTextPaint.setColor(0xFF000000); // default to a single line of text int width = (int) mTextPaint.measureText(mText); mStaticLayout = new StaticLayout(mText, mTextPaint, (int) width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false); // New API alternate // // StaticLayout.Builder builder = StaticLayout.Builder.obtain(mText, 0, mText.length(), mTextPaint, width) // .setAlignment(Layout.Alignment.ALIGN_NORMAL) // .setLineSpacing(1, 0) // multiplier, add // .setIncludePad(false); // mStaticLayout = builder.build(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Tell the parent layout how big this view would like to be // but still respect any requirements (measure specs) that are passed down. // determine the width int width; int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthRequirement = MeasureSpec.getSize(widthMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { width = widthRequirement; } else { width = mStaticLayout.getWidth() + getPaddingLeft() + getPaddingRight(); if (widthMode == MeasureSpec.AT_MOST) { if (width > widthRequirement) { width = widthRequirement; // too long for a single line so relayout as multiline mStaticLayout = new StaticLayout(mText, mTextPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false); } } } // determine the height int height; int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightRequirement = MeasureSpec.getSize(heightMeasureSpec); if (heightMode == MeasureSpec.EXACTLY) { height = heightRequirement; } else { height = mStaticLayout.getHeight() + getPaddingTop() + getPaddingBottom(); if (heightMode == MeasureSpec.AT_MOST) { height = Math.min(height, heightRequirement); } } // Required call: set width and height setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // do as little as possible inside onDraw to improve performance // draw the text on the canvas after adjusting for padding canvas.save(); canvas.translate(getPaddingLeft(), getPaddingTop()); mStaticLayout.draw(canvas); canvas.restore(); } }
activity_main.xml中
笔记
这个,这个,这对于学习如何创建自定义文本处理视图很有用.
如果要添加可以从代码或xml设置的自定义属性,请参阅创建视图类.