先看显示效果如下:
textview本身属性可以实现汉字的竖直显示,只需要将会android:ems属性设置为1,设置单行属性为false就行,但是对英文,它的显示则较为难看。对于英文也想要显示成旋转90度那种,就需要绘制。所以咱们今天重点说如何绘制竖直单列文本显示。
首先需要新建一个类继承TextView,然后创建初始化文本,及画笔paint,然后初始化画笔,配置文字颜色,大小及风格。然后重写TextView中的onDraw方法,根据自己的需求绘制文本。
我们需要绘制单列显示的文本,绘制之前需要计算文字的宽度,使用如下方法计算汉字文本的宽度,此文本宽度是你进行文字大小设置之后的文字宽度像素值。随着文字大小的改变而变化。
A = mPaint.measureText("正", 0, 1);
然后计算出我们开始绘制单列文本的横纵坐标,根据自身需求。这里文本显示的效果是横向居中,所以我们的绘制坐标应该是y坐标值为0,x坐标值通过以下方式去计算。
X= getWidth()/2-A/2;
getWidth()为获取显示区域的宽度。A为上文文字的宽度。因为文字要横向居中,所以我们要从文字本身的左边开始绘制。这里还需要计算文字的长度,做一个for循环,一个字符一个字符去绘制。还要在for循环中插入一个if语句用以判断此字符是否为中文。是和不是需要进行不同的绘制,代码如下;
final int len = mText.length();
float py = 0 ;
for(int i=0; i<len; i ++){
char c = mText.charAt(i);
w = mPaint.measureText(mText, i, i+1);//获取字符宽度
Log.d(TAG,"tongfei ---w= "+w);
StringBuffer b = new StringBuffer();
b.append(c);
if(py > getHeight()){//定义字的范围
return;
}
if(isChinese(c)){
py += w;
if(py > getHeight()){
return;
}
canvas.drawText(b.toString(), left, py, mPaint); //中文处理方法
}else {
canvas.drawTextOnPath(b.toString(), path, py, -left-2, mPaint);//其他文字处理方法
py += w;
}
}
进行中英文区分,用以下方法,中文的绘制就是,每次绘制只增加其纵坐标,横坐标的绘制不变。
英文字母绘制和中文差不多,只需要将绘制坐标进行反向就好(坐标前加个负号),再将横纵坐标调换即可。
//区分中英文
public boolean isChinese(char str) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(str);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}
以下就是整个自定义textview的全部代码。
public class MyTextview extends TextView {
private static final boolean DBG = true;
// never public, so that another class won't be messed up.
private final static String TAG = "MyTextview ";
protected int mBackcolor;
protected int mTextColor;
private String mText;
private Paint mPaint;
private Rect mBound;//绘制时控制文本绘制的范围
private int width = -1;
private int height = -1;
private float top = 18;
private Rect mRect;
private Timer mTimer;
private Path path;
public MyTextview (Context context) {
super(context);
}
public MyTextview (Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();//创建画笔
mText="n你好,世界,hellow world";// 初始化文本
mPaint.setColor(FFFFFFFF);//初始化画笔颜色
mBound = new Rect();//显示区域
mPaint.getTextBounds(mText, 0, mText.length(), mBound);
mPaint.clearShadowLayer();
initDisplay();
path = new Path();
path.lineTo(0,500);
}
public MyTextview (Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
protected void initDisplay(ProgramParser.Item item) {
//RectColor
setBackgroundColor(mBackcolor);//初始化显示区域颜色
//Size
mPaint.setTextSize(Float.parseFloat(18));//初始化文字大小
//style
int style = Typeface.NORMAL;
style = Typeface.ITALIC;
mPaint.setTextSkewX(-0.25f);
style |= Typeface.BOLD;
mPaint.setFlags(Paint.FAKE_BOLD_TEXT_FLAG | getPaint().getFlags());
if ("1".equals( item.logfont.lfUnderline)) {
mPaint.setFlags(Paint.UNDERLINE_TEXT_FLAG | getPaint().getFlags());
}
Typeface typeface = AppController.getInstance().getTypeface(item.logfont.lfFaceName);
if (typeface == null)
typeface = Typeface.defaultFromStyle(style);
if (DBG)
Log.d(TAG, "style= " + style + ", lfFaceName= " + item.logfont.lfFaceName +
", typeface= " + typeface +
((typeface == null)? "" : ", current style= " + typeface.getStyle()));
setTypeface(Typeface.SERIF);//风格设置
}
@Override
public boolean isFocused() {
return true;
}
public boolean isChinese(char str) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(str);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float a = mPaint.measureText("正正", 0, 1);
float left = getWidth()/2-a/2;
float w;
final int len = mText.length();
float py = 0 ;
for(int i=0; i<len; i ++){
char c = mText.charAt(i);
w = mPaint.measureText(mText, i, i+1);//获取字符宽度
Log.d(TAG,"tongfei ---w= "+w);
StringBuffer b = new StringBuffer();
b.append(c);
if(py > getHeight()){//定义字的范围
return;
}
if(isChinese(c)){
py += w;
if(py > getHeight()){
return;
}
canvas.drawText(b.toString(), left, py, mPaint); //中文处理方法
}else {
canvas.drawTextOnPath(b.toString(), path, py, -left-2, mPaint);//其他文字处理方法
py += w;
}
}
}
}