textview下划线(辅助文本)

时间:2016-05-24 20:14:56

标签: android textview spannablestring spannable

如何在TextView中创建辅助线(下划线)?

例如

第1行:

 |word1      word2       word3 word4|   //size17

 |      word2 description           |   //size 6

第2行:

 |word4 word5 word6      word7      |   //size17

 |                word7 description |   //size6

编辑27.05:

预览版。如何改进?

public class DescriptionSpan extends ReplacementSpan {


String description;
Paint descriptionPaint;

public DescriptionSpan(Paint paint, String description) {
    descriptionPaint = paint;
    this.description = description;
}


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

    float delta = getShift(paint, text.subSequence(start, end).toString(), description);

    if (delta >= 0) {
        canvas.drawText(text, start, end, x, y, paint);
        canvas.drawText(description, 0, description.length(), x + delta, y + descriptionPaint.getTextSize(), descriptionPaint);
    } else {
        canvas.drawText(text, start, end, x - delta, y, paint);
        canvas.drawText(description, 0, description.length(), x, y + descriptionPaint.getTextSize(), descriptionPaint);
    }
}

@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
    return (int) Math.max(paint.measureText(text, start, end), descriptionPaint.measureText(description));
}


private float getShift(Paint paint, String text, String description) {
    return (paint.measureText(text) - descriptionPaint.measureText(description)) / 2;
}

2 个答案:

答案 0 :(得分:1)

我不喜欢在没有代码的情况下写答案;但是,我在这方面花了太长时间(在编码方面我无法抗拒挑战)而且我认为我有足够的信息可以让你在没有正常工作代码的情况下朝着正确的方向前进。 / p>

以及返回跨度宽度。

但事情就是这样:getSize()的唯一具体实现是FontMetricsInt,它扩展了ReplacementSpanImageSpan}。如果你看DynamicDrawableSpan,它会将下降和底部设置为零,并将上升和顶部设置为可绘制的大小。更多关于这一点。

当我拿到你的代码并尝试将字体度量逻辑添加到ReplacementSpan时,我遇到了一些问题。

  1. 上升/上限的变化很受欢迎,但是对底部的任何更改 - 需要经过调整才能为您的描述留出空间 - 。似乎逻辑是为了适应DynamicDrawableSpan / getSize()而量身定制的,其他所有内容都被视为未经测试的角落案例。

  2. ImageSpan似乎是单行文字的目标。上升和放大top在第一段中正确设置,但在换行后,恢复正常的上升/顶部。

  3. 跨度通常被视为一个非破坏性的词,但我确实遇到了间歇性的错误,其中跨度本身被包裹在第二行。显然,这将是计算将所有文本放在何处的问题。

  4. 因此,如果你真的想用跨度来做这件事,我认为你需要做的是另一个自定义的段落样式跨度来实现DynamicDrawableSpan。为此,您将实现ReplacementSpan。这是如何工作的,将为段落中的每一行调用LineHeightSpan。您的实现将在该行上查找chooseHeight()并设置字体度量以适应描述文本。因此,您将使用此段落样式范围包装具有chooseHeight() s的每个段落。在此范围内,DescriptionSpan不会更改DescriptionSpan中的字体指标,您只需假设DescriptionSpan中的说明文字有空格即可。 (我希望画布不会被剪裁到跨度边界。自定义视图的想法会让你看起来越来越好。)

    我很乐意让代码正常运行并发布,但我花了太多时间在getSize()字体指标上敲打。

答案 1 :(得分:0)

您可以使用SpannableStringBuilder。如下所示:

SpannableStringBuilder span = new SpannableStringBuilder();
    span.append("First Line");
    span.setSpan(new RelativeSizeSpan(.8f),0,firstLineLength);
    span.append("Second Line");
    span.setSpan(new RelativeSizeSpan(1f),firstLineLength,firstLineLength+secondLineLength);
textView.setText(span);