下面列出了android.text.Layout#getSpacingMultiplier ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Prior to version 20, If the Layout specifies extra space between lines (either by spacingmult
* or spacingadd) the StaticLayout would erroneously add this space after the last line as well.
* This bug was fixed in version 20. This method calculates the extra space and reduces the height
* by that amount.
*
* @param layout The layout.
* @return The height of the layout.
*/
public static int getHeight(Layout layout) {
if (layout == null) {
return 0;
}
int extra = 0;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT_WATCH
&& layout instanceof StaticLayout) {
int line = Math.max(0, layout.getLineCount() - 1);
int above = layout.getLineAscent(line);
int below = layout.getLineDescent(line);
float originalSize = (below - above - layout.getSpacingAdd()) / layout.getSpacingMultiplier();
float ex = below - above - originalSize;
if (ex >= 0) {
extra = (int) (ex + 0.5);
} else {
extra = -(int) (-ex + 0.5);
}
}
return layout.getHeight() - extra;
}
private static float getLineBottomWithoutSpacing(@NonNull Layout layout, int line) {
final float value = layout.getLineBottom(line);
final boolean isLastLineSpacingNotAdded = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
final boolean isLastLine = line == (layout.getLineCount() - 1);
final float lineBottomWithoutSpacing;
final float lineSpacingExtra = layout.getSpacingAdd();
final float lineSpacingMultiplier = layout.getSpacingMultiplier();
final boolean hasLineSpacing = Float.compare(lineSpacingExtra, .0F) != 0
|| Float.compare(lineSpacingMultiplier, 1F) != 0;
if (!hasLineSpacing || isLastLine && isLastLineSpacingNotAdded) {
lineBottomWithoutSpacing = value;
} else {
final float extra;
if (Float.compare(lineSpacingMultiplier, 1F) != 0) {
final float lineHeight = getLineHeight(layout, line);
extra = lineHeight - (lineHeight - lineSpacingExtra) / lineSpacingMultiplier;
} else {
extra = lineSpacingExtra;
}
lineBottomWithoutSpacing = value - extra;
}
return lineBottomWithoutSpacing;
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
.getSpacingAdd());
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart,
lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
mLineY += textHeight;
}
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
.getSpacingAdd());
//解决了最后一行文字间距过大的问题
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart,
lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (i < layout.getLineCount() - 1) {
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
} else {
canvas.drawText(line, 0, mLineY, paint);
}
mLineY += textHeight;
}
}
public static int getLineBottomWithoutPaddingAndSpacing(
@NonNull Layout layout,
int line
) {
final int bottom = layout.getLineBottom(line);
final boolean lastLineSpacingNotAdded = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
final boolean isSpanLastLine = line == (layout.getLineCount() - 1);
final int lineBottom;
final float lineSpacingExtra = layout.getSpacingAdd();
final float lineSpacingMultiplier = layout.getSpacingMultiplier();
// simplified check
final boolean hasLineSpacing = lineSpacingExtra != DEFAULT_EXTRA
|| lineSpacingMultiplier != DEFAULT_MULTIPLIER;
if (!hasLineSpacing
|| (isSpanLastLine && lastLineSpacingNotAdded)) {
lineBottom = bottom;
} else {
final float extra;
if (Float.compare(DEFAULT_MULTIPLIER, lineSpacingMultiplier) != 0) {
final int lineHeight = getLineHeight(layout, line);
extra = lineHeight -
((lineHeight - lineSpacingExtra) / lineSpacingMultiplier);
} else {
extra = lineSpacingExtra;
}
lineBottom = (int) (bottom - extra + .5F);
}
// check if it is the last line that span is occupying **and** that this line is the last
// one in TextView
if (isSpanLastLine
&& (line == layout.getLineCount() - 1)) {
return lineBottom - layout.getBottomPadding();
}
return lineBottom;
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
width = getMeasuredWidth();
String text = getText().toString();
Paint.FontMetrics fm = paint.getFontMetrics();
// 计算行高
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
textHeight = fm.descent - fm.ascent;
textHeight = textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd();
float firstHeight = getTextSize();
int gravity = getGravity();
if ((gravity & 0x1000) == 0) { // 是否垂直居中
firstHeight = firstHeight + (textHeight - firstHeight) / 2;
}
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
width = width - paddingLeft - paddingRight;
lines.clear();
tailLines.clear();
// 文本含有换行符时,分割单独处理
String[] items = text.split("\\n");
for (String item : items) {
calc(paint, item);
}
for (int i = 0; i < lines.size(); i++) {
float drawY = i * textHeight + firstHeight;
String line = lines.get(i);
// 绘画起始x坐标
float drawSpacingX = paddingLeft;
float gap = (width - paint.measureText(line));
float interval = gap / (line.length() - 1);
// 绘制最后一行
if (tailLines.contains(i)) {
interval = 0;
if (align == Align.ALIGN_CENTER)
drawSpacingX += gap / 2;
else if (align == Align.ALIGN_RIGHT)
drawSpacingX += gap;
}
for (int j = 0; j < line.length(); j++) {
float drawX = paint.measureText(line.substring(0, j))
+ interval * j;
canvas.drawText(line.substring(j, j + 1), drawX + drawSpacingX,
drawY, paint);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
// 返回绘制状态的资源ID数组表示视图的当前状态
paint.drawableState = getDrawableState();
// 对View上的内容进行测量后得到的View内容占据的宽度
// 前提是你必须在父布局的onLayout()方法或者此View的onDraw()方法里调用measure(0,0);
// 否则你得到的结果和getWidth()得到的结果一样。
mViewWidth = getMeasuredWidth();
// 获取文本
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
// 获取用于显示当前文本的布局
Layout layout = getLayout();
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());
for (int i = 0; i < layout.getLineCount(); i++) {
// 返回文本中的指定行开头的偏移
int lineStart = layout.getLineStart(i);
// 返回文本中的指定行最后一个字符的偏移
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if (line.equals("")) {
break;
}
if (i < layout.getLineCount() - 1) {
if (needScale(line)) {
drawScaledText(canvas, lineStart, line, width);
} else {
canvas.drawText(line, 0, mLineY, paint);
}
} else {
canvas.drawText(line, 0, mLineY, paint);
}
// 增加行高
mLineY += textHeight;
}
}