TextViewVertical实现文字并列竖排 如古诗,蒙古语等

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

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值