一个SpannableString在一个TextView Ellipsize各条线 [英] Ellipsize individual lines of a SpannableString in a TextView

查看:621
本文介绍了一个SpannableString在一个TextView Ellipsize各条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的TextView 存储的地址,它是两条线长。这条街的推移第一线,是大胆的。城市和放大器;状态去在第二行上,并且不粗体。我想ellipsized每一行结束时,如果在该行的各个文本跑过去。我使用的是 SpannableString 存储地址,因为我想要的街道地址大胆地将城市和放大器;状态是不加粗。

有没有办法做到这一点,是不是不使用两项共计破解 TextViews 的每一行?

示例输出:

例如:
123812华盛顿...
斯克内克塔迪新尤尔...

例如:
2792 Dantzler Boulev ...
查尔斯顿SC,29406

例如:
3大街
亚特兰大

解决方案

我有同样的问题,并通过创建一个EllipsizeLineSpan类解决了

。你可以用你想ellipsize它的每一行。

为例来标记一个spannable字符串是:

  SpannableStringBuilder textspan =新SpannableStringBuilder(#1.Lorem存有悲坐阿梅德,consectetur adipisicing ELIT,sed的根本eiusmod tempor incididunt UT labore等dolore麦格纳aliqua。\ N+
    从ellipsizing#2.Lorem存有悲保护坐阿梅德,consectetur adipisicing ELIT,sed的根本eiusmod tempor incididunt UT labore等dolore麦格纳aliqua。\ N+
    #3.Lorem存有悲坐阿梅德,consectetur adipisicing ELIT \ N+
    #4.Lorem存有悲坐阿梅德,consectetur adipisicing ELIT,sed的根本eiusmod tempor incididunt UT labore等dolore麦格纳aliqua \ñ。);

//找到ellipsizable文本(从#到换行符)
模式模式= Pattern.compile(#* \\名,Pattern.CASE_INSENSITIVE);
匹配匹配= pattern.matcher(textspan);
而(matcher.find()){
    textspan.setSpan(新EllipsizeLineSpan(),matcher.start(),matcher.end(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
 

EllipsizeLineSpan:

 公共类EllipsizeLineSpan扩展ReplacementSpan实现LineBackgroundSpan {
INT layoutLeft = 0;
INT layoutRight = 0;

公共EllipsizeLineSpan(){
}

@覆盖
公共无效drawBackground(帆布C,涂料P,
                            INT左,右INT,
                            INT顶部,诠释基线,INT底部,
                            CharSequence的文字,诠释开始,诠释年底,
                            lnum缓冲区里的INT){
    矩形CLI preCT =新的矩形();
    c.getClipBounds(CLI $ P $厘);
    layoutLeft = CLI prect.left;
    layoutRight = CLI prect.right;
}

@覆盖
公众诠释的getSize(油漆涂料,CharSequence的文字,诠释开始,诠释年底,
                    Paint.FontMetricsInt FM){
    返回layoutRight  -  layoutLeft;
}

@覆盖
公共无效画(油画画布,CharSequence的文字,诠释开始,诠释年底,
                  浮动X,INT顶部,INT Y,INT底部,油漆涂料){
    浮动输出textWidth = paint.measureText(文本,开始,结束);

    如果(X +(INT)Math.ceil(输出textWidth)< layoutRight){//文本适合
        canvas.drawText(文本,开始,结束,X,Y,油漆);
    } 其他 {
        浮ellipsiswid = paint.measureText(\ U2026);
        //此举结束以省略号点
        结束=启动+ paint.breakText(文本,开始,结束,真正的,layoutRight  -  X  -  ellipsiswid,NULL);
        canvas.drawText(文本,开始,结束,X,Y,油漆);
        canvas.drawText(\ U2026,X + paint.measureText(文本,开始,结束),Y,油漆);

    }

}


}
 

I have a TextView storing an address that is two lines long. The street goes on the first line and is bold. The city & state go on the second line and are not bold. I want the end of each line ellipsized if the individual text on that line runs over. I'm using a SpannableString to store the address because I want the street address to be bold and the city & state to be not bold.

Is there a way to do this that isn't a total hack without using two TextViews for each line?

Example outputs:

Ex:
123812 Washington A...
Schenectady New Yor...

Ex:
2792 Dantzler Boulev...
Charleston SC, 29406

Ex:
3 Main Street
Atlanta GA

解决方案

I had the same problem and solved it by creating an EllipsizeLineSpan class. You can wrap each line that you want to ellipsize with it.

Example for marking up a spannable string with it:

SpannableStringBuilder textspan = new SpannableStringBuilder("#1.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"+
    "Protect from ellipsizing #2.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n"+
    "#3.Lorem ipsum dolor sit amet, consectetur adipisicing elit\n"+
    "#4.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n");

// find  ellipsizable text (from '#' to newline)
Pattern pattern = Pattern.compile("#.*\\n", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(textspan);
while(matcher.find()) {
    textspan.setSpan(new EllipsizeLineSpan(), matcher.start(), matcher.end(),   Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

EllipsizeLineSpan:

public class EllipsizeLineSpan extends ReplacementSpan implements LineBackgroundSpan {
int layoutLeft = 0;
int layoutRight = 0;

public EllipsizeLineSpan () {
}

@Override
public void drawBackground (Canvas c, Paint p,
                            int left, int right,
                            int top, int baseline, int bottom,
                            CharSequence text, int start, int end,
                            int lnum) {
    Rect clipRect = new Rect();
    c.getClipBounds(clipRect);
    layoutLeft = clipRect.left;
    layoutRight = clipRect.right;
}

@Override
public int getSize (Paint paint, CharSequence text, int start, int end,
                    Paint.FontMetricsInt fm) {
    return layoutRight - layoutLeft;
}

@Override
public void draw (Canvas canvas, CharSequence text, int start, int end,
                  float x, int top, int y, int bottom, Paint paint) {
    float textWidth = paint.measureText(text, start, end);

    if (x + (int) Math.ceil(textWidth) < layoutRight) {  //text fits
        canvas.drawText(text, start, end, x, y, paint);
    } else {
        float ellipsiswid = paint.measureText("\u2026");
        // move 'end' to the ellipsis point
        end = start + paint.breakText(text, start, end, true, layoutRight - x - ellipsiswid, null);
        canvas.drawText(text, start, end, x, y, paint);
        canvas.drawText("\u2026", x + paint.measureText(text, start, end), y, paint);

    }

}


}

这篇关于一个SpannableString在一个TextView Ellipsize各条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆