Android 可跨行高

Posted

技术标签:

【中文标题】Android 可跨行高【英文标题】:Android Spannable Line Height 【发布时间】:2012-10-06 17:40:54 【问题描述】:

最近几天我一直在尝试解决这个问题,但没有成功......

我现在正在学习android,目前正在创建一个带有历史的计算器作为我的学习项目。我有一个负责显示所有历史记录的 TextView……我使用的是一种看起来像计算器字体的数字字体,但这仅适用于数字、小数和逗号。我希望所有运算符都以不同的字体突出显示(目前为 Arial Narrow)。我已经能够使用一个可扩展的字符串很好地工作,我在其中指定字体颜色以及使用 CustomTypeFaceSpan 类应用我的自定义字体的字体。

问题...当我混合字体时,行高似乎有问题,所以我找到了this post,它演示了使用另一个自定义类将行高应用于每行添加的可跨文本:

public class CustomLineHeightSpan implements LineHeightSpan
    private final int height;

    public CustomLineHeightSpan(int height)
        this.height = height;
    

    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, FontMetricsInt fm) 
        fm.bottom += height;
        fm.descent += height;
    


这似乎不起作用,我不知道为什么。如果我不应用不同的字体,那么它会按预期显示,第一行上方没有空格,行间距约为 5px。当我应用备用字体时,第一行文本上方大约有 10 到 15 像素的空间,而行距大约是 10 到 15 像素。

字体大小没有区别,只有字体。我错过了什么。我实现了 CustomLineHeightSpan,它实现了 LineHeightSpan 并覆盖了 chooseHeight 方法。我这样称呼它:

WordtoSpan.setSpan(new CustomLineHeightSpan(10), operatorPositions.get(ii), operatorPositions.get(ii) + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

我在 CustomLineHeightSpan 的调用中添加了什么似乎并不重要。什么都没有改变...

任何人都知道我错过了什么......我确定这是一个“我不敢相信我错过了”的答案,但目前似乎无法弄清楚。

感谢大家的帮助:-)

【问题讨论】:

这能回答你的问题吗? Individual line spacing for each line 看这个:***.com/a/59048332/2603965 【参考方案1】:

我终于找到了一个更深入的使用 LineHeightSpan 的示例...实际上 LineHeightSpan.WithDensity 更准确...以下是帮助我解决问题的摘录:

private static class Height implements LineHeightSpan.WithDensity 
    private int mSize;
    private static float sProportion = 0;

    public Height(int size) 
        mSize = size;
    

    public void chooseHeight(CharSequence text, int start, int end,
                             int spanstartv, int v,
                             Paint.FontMetricsInt fm) 
        // Should not get called, at least not by StaticLayout.
        chooseHeight(text, start, end, spanstartv, v, fm, null);
    

    public void chooseHeight(CharSequence text, int start, int end,
                             int spanstartv, int v,
                             Paint.FontMetricsInt fm, TextPaint paint) 
        int size = mSize;
        if (paint != null) 
            size *= paint.density;
        

        if (fm.bottom - fm.top < size) 
            fm.top = fm.bottom - size;
            fm.ascent = fm.ascent - size;
         else 
            if (sProportion == 0) 
                /*
                 * Calculate what fraction of the nominal ascent
                 * the height of a capital letter actually is,
                 * so that we won't reduce the ascent to less than
                 * that unless we absolutely have to.
                 */

                Paint p = new Paint();
                p.setTextSize(100);
                Rect r = new Rect();
                p.getTextBounds("ABCDEFG", 0, 7, r);

                sProportion = (r.top) / p.ascent();
            

            int need = (int) Math.ceil(-fm.top * sProportion);

            if (size - fm.descent >= need) 
                /*
                 * It is safe to shrink the ascent this much.
                 */

                fm.top = fm.bottom - size;
                fm.ascent = fm.descent - size;
             else if (size >= need) 
                /*
                 * We can't show all the descent, but we can at least
                 * show all the ascent.
                 */

                fm.top = fm.ascent = -need;
                fm.bottom = fm.descent = fm.top + size;
             else 
                /*
                 * Show as much of the ascent as we can, and no descent.
                 */

                fm.top = fm.ascent = -size;
                fm.bottom = fm.descent = 0;
            
        
    

这取自this example。

它的作用如下:

强制文本行为指定高度,收缩/拉伸 如果可能,上升,或者如果进一步缩小上升,下降 会使文本不可读。

我希望这对下一个人有帮助:-)

【讨论】:

这个方法怎么调用chooseHeight? Android 内部调用此方法。您所要做的就是给您的 String 跨度。如果您想了解更多信息,请查看 android.text.StaticLayout 类。其他 span 的方法也在那里调用。 如果我们见面,我欠你一杯啤酒(或其他选择的饮料)——这些东西是超级无证的,找到它需要很长时间。 +1。奇迹般有效。一个问题:是否可以将文本垂直居中? 这很好用,但如果这会影响整个段落的间距而不是单行。我如何在段落中的单行上应用它?

以上是关于Android 可跨行高的主要内容,如果未能解决你的问题,请参考以下文章

将 TextView 左对齐和居中对齐

具有行距的 Android 可跨字符串

支持 RTL 语言的 Android Justify 可跨文本视图

Android Calendar Provider:是不是有可跨多个设备使用的事件唯一标识符?

一起Talk Android吧(第四百零一回:如何使用TableLayout布局)

Android如何设置TextView的行间距行高