2016-05-24 45 views
0

如何在TextView中创建辅助线(下划线)?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; 
} 

看起来你的文章主要是代码;请添加一些更多的细节....

+0

我猜你并不是说这是一个文本网格,而是你的意思是这些文字是在一个段落的行内,并且在一个指定的单词中,你需要在该单词下面有一些辅助文本。这是否准确?也许你可以多说一下你在用这个文本显示器做什么。 –

+0

是的。基本上需要描述(顶部或底部)单词 –

+1

这至少需要一个自定义Span子类。我会看看这个。如果有人给我这个代码,我会考虑写一个自定义视图,并直接进行所有的文本测量/计算/渲染。 –

回答

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

当前解决方案创建了像cCcCcCcC这样的文本。计算描述的位置看起来很难用于不同的多行文本。 –

1

我不喜欢写没有代码的答案;然而,我在这方面花了太长时间(在编码方面我无法抗拒挑战),并且我认为我有足够的信息让您在没有工作代码示例的情况下朝正确的方向发展。

的方式应该的工作是,在getSize()你会设置在以适当的高度,通过您的跨度FontMetricsInt,以及返回的跨度。

但事情是这样的:ReplacementSpan的唯一具体实现是ImageSpan,它扩展了DynamicDrawableSpan(这是一个ReplacementSpan)。如果您查看DynamicDrawableSpan,它会将下降和底部设置为零,并将上升和顶部设置为可绘制的大小。更多关于这一秒。

当我把你的代码,并试图将字体度量逻辑添加到getSize(),我遇到了几个问题。

  1. 变化上升/顶部很荣幸,但任何改变底部 - 这将需要调整,以留出空间的描述 - 是兑现。看起来这个逻辑是为适应ImageSpan/DynamicDrawableSpan而定制的,而其他一切都被视为未经测试的角落案例。

  2. ReplacementSpan似乎是单行文本的目标。在第一段行中正确设置了顶部&顶部,但在换行后,恢复正常上升/顶部。

  3. 跨度通常被当作非破坏性单词处理,但我确实碰到间歇性错误,其中跨度本身被缠绕到第二行。显然,这将是计算放置所有文本的位置的问题。

所以如果你真的想和跨度要做到这一点,我认为你必须做的就是有一个实现LineHeightSpan另一个定制款风格跨度。为此,您可以实施chooseHeight()。这是如何工作的,将为段落中的每一行调用chooseHeight()。您的实现将在该行上查找DescriptionSpan,并设置字体指标以适应说明文本。所以你会用这个段落样式范围来包装每一个有DescriptionSpan的段落。有了这个跨度,您的DescriptionSpan不会改变getSize()中的字体指标,并且您只是假设在draw()中有描述文字的空间。 (我希望画布不会被限制在跨度范围内,这种自定义视图的想法只会让画面看起来越来越好)

我很想让代码工作并发布,但我花了太多时间敲打我的头上ReplacementSpan字体指标。

+0

是的,我知道。在空闲时间,我会尝试扩展这个解决方案。对于当前的任务,这已经足够了(字/翻译不占用大量空间,lineSpacingMultiplier会占用额外的空间)。我不想使用自己的观点。我认为这将足以添加像[numberLine = measure/lineLenght +1; FontMetricsInt.bottom * numberLine; foreach画线] –