1. 今天忽然想嘚瑟一下,就在csdn上搞了个博客,发表我的处女文章.
2. 因为公司需求做一个蒙语显示的东东,最开始的时候想的是在textView上设置啊啥的,确实能实现换列的功能,但是在效果上差了很多,这个是借鉴一个git上的大神写的(名字忘记了,在此膜拜一下他的无私奉献),我在上面进行了一些优化:a默认最长的列为控件的高,b去掉了文字右排列的功能,保留左排列(需要的可以去git找原文)
/**多个竖列,空格符为换列标记
*
*@author lvmin 2015-10-26
*/
public class TextViewVertical extends View {
private AttributeSet attrs;
private Paint paint;
private FontMetrics fm;
private String text="";
private int fontWidth = 0,fontHeight;// 字宽,字高
private int viewWidt = 0,viewHeight = 0;// 视图的宽,高
private float fontSize = 24;// 默认字体大小为24
private int fontColor=Color.parseColor("#333333");// 默认字体颜色
public TextViewVertical(Context context){
super(context);
initPaint();
initFontInfo();
}
public TextViewVertical(Context context,AttributeSet attrs){
super(context, attrs);
this.attrs=attrs;
initPaint();
initFontInfo();
}
/**设置内容*/
public void setText(String text){
this.text = text;
invalidate();
requestLayout();
}
/**设置字体大小*/
public final void setTextSize(float size) {
if (size != paint.getTextSize()) {
fontSize=size;
initFontInfo();
invalidate();
requestLayout();
}
}
/**设置字体颜色*/
public final void setTextColor(int color) {
if (color != paint.getColor()) {
paint.setColor(color);
invalidate();
}
}
@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
// 为了初始化的时候获取到控件的高用于判断超出绘制的高度的后换列
viewHeight = MeasureSpec.getSize(heightMeasureSpec);
initMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void initMeasure(int widthMeasureSpec,int heightMeasureSpec){
int columnHeight = 0;// 当前列的高度
int columnHeightMax = 0;// 缓存最大的高度
int column = 1;// 列数
char ch;
for(int i = 0;i < text.length();i++){
ch = text.charAt(i);
if(ch == '\n'){
column = column + 1;
columnHeight = 0;
}else{
// 超出绘制的高度的后换列显示
columnHeight += fontHeight;
if(columnHeight > this.viewHeight){
column++;// 换列
i--;
columnHeight = 0;
}else{
if(columnHeightMax < columnHeight){
columnHeightMax = columnHeight;
}
}
}
}
viewWidt = fontWidth * column;// 计算文字总宽度
viewHeight = columnHeightMax + fontHeight / 2;// 计算最高高度
int width = resolveSizeAndState_1(viewWidt, widthMeasureSpec, 0);
int height = resolveSizeAndState_1(viewHeight, heightMeasureSpec, 0);
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
drawFont(canvas);
}
private void drawFont(Canvas canvas){
char ch;
float fontX = fontWidth / 2;
float fontY = 0;
for(int i = 0;i < text.length();i++){
ch = text.charAt(i);
if(ch == '\n'){
fontX += fontWidth;// 换列
fontY = 0;
}else{
fontY += fontHeight;
if(fontY > this.viewHeight){
// 超出绘制的高度的后换列显示
fontX += fontWidth;// 换列
i--;
fontY = 0;
}else{
canvas.drawText(String.valueOf(ch), fontX, fontY, paint);
}
}
}
}
private void initPaint(){
paint = new Paint();// 新建画笔
paint.setTextAlign(Align.CENTER);// 文字居中
paint.setAntiAlias(true);// 平滑处理
if(attrs != null){
try{
fontSize = Float.parseFloat(attrs.getAttributeValue(null, "textSize"));// 获取字体大小属性
fontColor= Integer.parseInt(attrs.getAttributeValue(null, "textColor"));// 获取字体大小属性
text= attrs.getAttributeValue(null, "text");// 获取字体大小属性
}catch(Exception e){
}
}
}
private void initFontInfo(){
paint.setColor(fontColor);// 默认文字颜色
paint.setTextSize(fontSize);
// 获得字宽
float[] widths = new float[1];
paint.getTextWidths("正", widths);// 获取单个汉字的宽度
fontWidth = (int) Math.ceil(widths[0] * 1.1 + 2);
// 获得字属性
fm = paint.getFontMetrics();
fontHeight = (int) (Math.ceil(fm.descent - fm.top) * 0.9);
//返回包围整个字符串的最小的一个Rect区域,但是在canvas.drawText()不好确定x,y位置
// Paint pFont = new Paint();
// Rect rect = new Rect();
// pFont.getTextBounds(str, 0, 1, rect);
// strwid = rect.width();
// strhei = rect.height();
}
// 新的api(resolveSizeAndState)无法兼容3.0以下,所以挖出来
private int resolveSizeAndState_1(int size,int measureSpec,int childMeasuredState){
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch(specMode){
case MeasureSpec.UNSPECIFIED:
result = size;
break;
case MeasureSpec.AT_MOST:
if(specSize < size){
result = specSize | 0x01000000;
}else{
result = size;
}
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result | (childMeasuredState & 0xff000000);
}
}
TextViewVertical实现文字并列竖排 如古诗,蒙古语等
最新推荐文章于 2021-07-22 21:28:42 发布