一个SpannableString的Ellipsize各行的一个TextView(Ellipsize

2019-08-19 07:57发布

我有一个TextView存储是两条线长的地址。 这条街的推移第一线和大胆。 这个城市和国家走在第二行和不大胆。 我想ellipsized每一行结束时,如果在该行个人文本跑过去。 我使用的是SpannableString存储地址,因为我想要的街道地址大胆地将城市和状态不大胆。

有没有办法做到这一点,是不是总不黑客使用两个TextViews的每一行?

示例输出:

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

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

例如:
3主街
亚特兰大

Answer 1:

我有同样的问题,并通过创建一个EllipsizeLineSpan类解决了这个问题。 你可以用你想用它ellipsize每一行。

例如用于标记一个spannable串吧:

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

    }

}


}


Answer 2:

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


Answer 3:

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

 android:ellipsize="end"


文章来源: Ellipsize individual lines of a SpannableString in a TextView