中英文混排对齐的TextView
This commit is contained in:
parent
f0b3e4da10
commit
c1e689384c
|
@ -0,0 +1,142 @@
|
|||
package com.zftlive.android.view;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.text.Layout;
|
||||
import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* 两端对齐的textview,可以设置最后一行靠左,靠右,居中对齐
|
||||
*
|
||||
* @author 曾繁添
|
||||
* @version 1.0
|
||||
*
|
||||
*/
|
||||
public class AlignTextView extends TextView {
|
||||
|
||||
private float textHeight; // 单行文字高度
|
||||
private int width; // textview宽度
|
||||
private List<String> lines = new ArrayList<String>(); // 分割后的行
|
||||
private List<Integer> tailLines = new ArrayList<Integer>(); // 尾行
|
||||
private Align align = Align.ALIGN_LEFT; // 默认最后一行左对齐
|
||||
|
||||
// 尾行对齐方式
|
||||
public enum Align {
|
||||
ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT; // 居中,居左,居右,针对段落最后一行
|
||||
}
|
||||
|
||||
public AlignTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置尾行对齐方式
|
||||
*
|
||||
* @param align
|
||||
*/
|
||||
public void setAlign(Align align) {
|
||||
this.align = align;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算每行应显示的文本数
|
||||
*
|
||||
* @param text
|
||||
* @return
|
||||
*/
|
||||
private void calc(Paint paint, String text) {
|
||||
if (text.length() == 0) {
|
||||
lines.add("\n");
|
||||
return;
|
||||
}
|
||||
StringBuffer sb = new StringBuffer("");
|
||||
int startPosition = 0; // 起始位置
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
if (paint.measureText(text.substring(startPosition, i + 1)) > width) {
|
||||
startPosition = i;
|
||||
lines.add(sb.toString());
|
||||
sb = new StringBuffer();
|
||||
}
|
||||
sb.append(text.charAt(i));
|
||||
}
|
||||
if (sb.length() > 0)
|
||||
lines.add(sb.toString());
|
||||
|
||||
tailLines.add(lines.size() - 1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue