Created
September 25, 2015 07:14
-
-
Save ityancs/711e398587273ff2c0fa to your computer and use it in GitHub Desktop.
A vertical TextView like Chinese old text style
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.graphics.Bitmap; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Matrix; | |
import android.graphics.Paint; | |
import android.graphics.Paint.Align; | |
import android.graphics.Paint.FontMetrics; | |
import android.graphics.Typeface; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.view.View; | |
public class TextViewVertical extends View { | |
private Paint paint; | |
private int mTextPosx = 0;// x坐标 | |
private int mTextPosy = 0;// y坐标 | |
private int mTextWidth = 0;// 绘制宽度 | |
private int mFontHeight = 0;// 绘制字体高度 | |
private float mFontSize = 24;// 字体大小 | |
private int mRealLine = 0;// 字符串真实的行数 | |
private int mLineWidth = 0;//列宽度 | |
private int TextLength = 0;//字符串长度 | |
private int MaxHeight = 500; | |
private String text = "";//待显示的文字 | |
private Matrix matrix; | |
private Align textStartAlign = Align.RIGHT;//draw start left or right.//default right | |
BitmapDrawable drawable = (BitmapDrawable) getBackground(); | |
public TextViewVertical(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
} | |
public TextViewVertical(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
matrix = new Matrix(); | |
paint = new Paint();//新建画笔 | |
paint.setTextAlign(Align.CENTER);//文字居中 | |
paint.setAntiAlias(true);//平滑处理 | |
paint.setColor(Color.BLACK);//默认文字颜色 | |
try { | |
mFontSize = Float.parseFloat(attrs.getAttributeValue(null, "textSize"));//获取字体大小属性 | |
} catch (Exception e) { | |
} | |
} | |
//设置文字 | |
public final void setText(String text) { | |
this.text = text; | |
this.TextLength = text.length(); | |
} | |
//设置字体大小 | |
public final void setTextSize(float size) { | |
if (size != paint.getTextSize()) { | |
mFontSize = size; | |
} | |
} | |
//设置字体颜色 | |
public final void setTextColor(int color) { | |
paint.setColor(color); | |
} | |
//设置字体颜色 | |
public final void setTextARGB(int a, int r, int g, int b) { | |
paint.setARGB(a, r, g, b); | |
} | |
//设置字体 | |
public void setTypeface(Typeface tf) { | |
if (this.paint.getTypeface() != tf) { | |
this.paint.setTypeface(tf); | |
} | |
} | |
//设置行宽 | |
public void setLineWidth(int LineWidth) { | |
mLineWidth = LineWidth; | |
} | |
//获取实际宽度 | |
public int getTextWidth() { | |
return mTextWidth; | |
} | |
@Override | |
protected void onDraw(Canvas canvas) { | |
super.onDraw(canvas); | |
Log.v("TextViewVertical", "onDraw"); | |
if (drawable != null) { | |
//画背景 | |
Bitmap b = Bitmap.createBitmap(drawable.getBitmap(), 0, 0, mTextWidth, MaxHeight); | |
canvas.drawBitmap(b, matrix, paint); | |
} | |
//画字 | |
draw(canvas, this.text); | |
} | |
private void draw(Canvas canvas, String thetext) { | |
char ch; | |
mTextPosy = 0;//初始化y坐标 | |
mTextPosx = textStartAlign == Align.LEFT ? mLineWidth : mTextWidth - mLineWidth;//初始化x坐标 | |
for (int i = 0; i < this.TextLength; i++) { | |
ch = thetext.charAt(i); | |
if (ch == '\n') { | |
if (textStartAlign == Align.LEFT) { | |
mTextPosx += mLineWidth;// 换列 | |
} else { | |
mTextPosx -= mLineWidth;// 换列 | |
} | |
mTextPosy = 0; | |
} else { | |
mTextPosy += mFontHeight; | |
if (mTextPosy > this.MaxHeight) { | |
if (textStartAlign == Align.LEFT) { | |
mTextPosx += mLineWidth;// 换列 | |
} else { | |
mTextPosx -= mLineWidth;// 换列 | |
} | |
i--; | |
mTextPosy = 0; | |
} else { | |
canvas.drawText(String.valueOf(ch), mTextPosx, mTextPosy, paint); | |
} | |
} | |
} | |
//调用接口方法 | |
//activity.getHandler().sendEmptyMessage(TestFontActivity.UPDATE); | |
} | |
//计算文字行数和总宽 | |
private void GetTextInfo(int heightMeasureSpec) { | |
Log.v("TextViewVertical", "GetTextInfo"); | |
char ch; | |
int h = 0; | |
paint.setTextSize(mFontSize); | |
//获得字宽 | |
if (mLineWidth == 0) { | |
float[] widths = new float[1]; | |
paint.getTextWidths("正", widths);//获取单个汉字的宽度 | |
mLineWidth = (int) Math.ceil(widths[0] * 1.1 + 2); | |
} | |
FontMetrics fm = paint.getFontMetrics(); | |
mFontHeight = (int) (Math.ceil(fm.descent - fm.top) * 0.9);// 获得字体高度 | |
String[] split = text.split("\n"); | |
int maxTextLength = 0; | |
for (String aSplit : split) { | |
int length = aSplit.length(); | |
if (length > maxTextLength) { | |
maxTextLength = length; | |
} | |
} | |
int measureHeight = MeasureSpec.getSize(heightMeasureSpec); | |
if (measureHeight > 0) { | |
int fontHeight = maxTextLength * mFontHeight; | |
if (fontHeight > measureHeight) { | |
MaxHeight = measureHeight; | |
} else { | |
MaxHeight = fontHeight; | |
} | |
} | |
//计算文字行数 | |
mRealLine = 0; | |
for (int i = 0; i < this.TextLength; i++) { | |
ch = this.text.charAt(i); | |
if (ch == '\n') { | |
mRealLine++;// 真实的行数加一 | |
h = 0; | |
} else { | |
h += mFontHeight; | |
if (h > (MaxHeight > 0 ? MaxHeight : 500)) { | |
mRealLine++;// 真实的行数加一 | |
i--; | |
h = 0; | |
} else { | |
if (i == this.TextLength - 1) { | |
mRealLine++;// 真实的行数加一 | |
} | |
} | |
} | |
} | |
mRealLine++;//额外增加一行 | |
mTextWidth = mLineWidth * mRealLine;//计算文字总宽度 | |
measure(mTextWidth, MaxHeight);//重新调整大小 | |
layout(getLeft(), getTop(), getLeft() + mTextWidth, getTop() + MaxHeight);//重新绘制容器 | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
Log.v("宽高", mTextWidth + ":" + MaxHeight); | |
if (mTextWidth == 0 || MaxHeight == 0) { | |
GetTextInfo(heightMeasureSpec); | |
} | |
setMeasuredDimension(mTextWidth, MaxHeight); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment