Android 在文本视图中省略号标注栏串的各行

Android 在文本视图中省略号标注栏串的各行,android,textview,ellipsis,spannablestring,Android,Textview,Ellipsis,Spannablestring,我有一个TextView存储了一个两行长的地址。这条街走在第一条线上,很醒目。城市和国家走在第二条线上,并不大胆。如果每一行上的单个文本都在上面,我希望每一行的结尾都被省略。我使用SpannableString来存储地址,因为我希望街道地址为粗体,城市和州地址为非粗体 有没有一种方法不需要对每行使用两个textview就可以做到这一点 示例输出: 例如: 123812华盛顿A 斯克内克塔迪纽约 例如: 2792丹茨勒·布列夫… 查尔斯顿南卡罗来纳州,29406 例如: 3大街 亚特兰大GA尝试在

我有一个
TextView
存储了一个两行长的地址。这条街走在第一条线上,很醒目。城市和国家走在第二条线上,并不大胆。如果每一行上的单个文本都在上面,我希望每一行的结尾都被省略。我使用
SpannableString
来存储地址,因为我希望街道地址为粗体,城市和州地址为非粗体

有没有一种方法不需要对每行使用两个
textview
就可以做到这一点

示例输出:

例如:
123812华盛顿A
斯克内克塔迪纽约

例如:
2792丹茨勒·布列夫…
查尔斯顿南卡罗来纳州,29406

例如:
3大街

亚特兰大GA

尝试在布局中设置椭圆大小,如:

 android:ellipsize="end"

我也遇到了同样的问题,通过创建一个EllipsizeLineSpan类解决了这个问题。您可以用它来包装要省略号的每一行

使用它标记可扩展字符串的示例:

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

    }

}


}
公共类EllipsizeLineSpan扩展替换span实现LineBackgroundSpan{
int layoutLeft=0;
int layoutRight=0;
公共EllipsizeLineSpan(){
}
@凌驾
公共空地(帆布c、油漆p、,
左整数,右整数,
整数顶部,整数基线,整数底部,
字符序列文本,int开始,int结束,
国际(南){
Rect clipRect=新的Rect();
c、 获取剪贴簿(clipRect);
layoutLeft=clipRect.left;
layoutRight=clipRect.right;
}
@凌驾
公共int getSize(绘制、字符序列文本、int开始、int结束、,
Paint.FontMetricsInt格式){
返回layoutRight-layoutLeft;
}
@凌驾
公共空白绘制(画布、字符序列文本、整数开始、整数结束、,
浮点数x、整数顶部、整数y、整数底部、油漆){
float textWidth=paint.measureText(文本、开始、结束);
如果(x+(int)Math.ceil(textWidth)
DangVarmit的答案对我帮助很大,但在使用了一段时间后,我发现有时文本的顶部偏移量随机不正确。以下是需要更换的零件:

  override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int, fontMetricsInt: Paint.FontMetricsInt?): Int {
    fontMetricsInt?.let {
        it.top = paint.getFontMetricsInt(it)
    }
    return Math.round(paint.measureText(text, start, start))
}

但这只会省略整个TextView的结尾。我想两行都要省略号。@erin我认为一个
TextView
是不可能的,放几个
TextView
s是一个技巧。是否可以在行尾添加“Protect from ellipzing”文本?假设您有一个像#(比如“^”)这样的字符前缀,然后需要从“^”之后测量文本,并减去计算中的测量值,移动“端点”。然后对“^”之后的剩余文本执行最后一个drawtext(),对我来说好的模式是:pattern.compile(“.\\n”,pattern.CASE\u不区分大小写);