【问题标题】:Ellipsize individual lines of a SpannableString in a TextView椭圆化 TextView 中 SpannableString 的单行
【发布时间】:2013-03-25 19:20:11
【问题描述】:

我有一个TextView 存储一个两行长的地址。这条街在第一行并且是粗体的。城市和州在第二行并且不粗体。如果该行上的单个文本超出,我希望每行的末尾都被省略。我使用SpannableString 来存储地址,因为我希望街道地址加粗,城市和州不加粗。

如果不为每行使用两个TextViews,有没有办法做到这一点,而不是完全破解?

示例输出:

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

例如:
2792 丹茨勒大道...
查尔斯顿 SC,29406

例如:
3大街
乔治亚州亚特兰大

【问题讨论】:

    标签: android textview ellipsis spannablestring


    【解决方案1】:

    我遇到了同样的问题,并通过创建一个 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);
    
        }
    
    }
    
    
    }
    

    【讨论】:

    • 是否可以在行尾添加“防止省略”文本?
    • 假设你有一个像 # 这样的字符前缀(比如 '^' ),那么你需要从 '^' 之后测量文本并在计算中减去测量值“终点”。然后对 '^' 之后的剩余文本执行最后一个 drawtext()
    • 对我来说好的模式是:Pattern.compile(".*\\n", Pattern.CASE_INSENSITIVE);
    【解决方案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))
    }
    

    【讨论】:

      【解决方案3】:

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

       android:ellipsize="end"
      

      【讨论】:

      • 但这只会省略整个 TextView 的末尾。我希望两条线都变成椭圆形。
      • @erin 我认为单个TextView 是不可能的,放入几个TextViews 是个技巧。
      猜你喜欢
      • 2013-09-09
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      相关资源
      最近更新 更多