Android中TextView实现竖直单列文本显示

先看显示效果如下:

                                                                       

        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;
            }
        }

    }

}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

童无极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值