Android Spannable Line Height

tit*_*tic 11 android textview spannablestring

我过去几天一直试图弄清楚这一点,并没有成功......

我现在正在学习机器人,目前正在创建一个带有历史记录的计算器作为我的学习项目.我有一个TextView负责显示所有历史...我使用的数字字体看起来像一个计算器字体,但这只适用于数字,小数和逗号.我希望所有操作符都以不同的字体突出显示(Arial Narrow).我已经能够使用spannable字符串精美地工作,我指定字体颜色以及使用CustomTypeFaceSpan类来应用我的自定义字体的字体.

问题...当我混合使用字体时,行高似乎存在问题,所以我发现这篇文章演示了如何使用另一个自定义类来为每个添加的spannable文本行应用行高:

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

}
Run Code Online (Sandbox Code Playgroud)

这似乎不起作用,我无法弄清楚为什么.如果我不应用不同的字体,那么它会按预期显示,第一行上方没有空格,行间距约为5px.当我应用替代字体时,在第一行文本上方有一个大约10到15px的空间,行间距大约相同10到15px.

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

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

我对CustomLineHeightSpan的调用似乎并不重要.没有什么变化...

任何人都知道我错过了什么......我确信这是一个"我不敢相信我错过了"的答案,但目前似乎无法弄明白.

谢谢你们的帮助:-)

tit*_*tic 21

我终于找到了一个更深入的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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是从这个例子中获得的.

它的作用如下:

强制文本行为指定高度,尽可能缩小/拉伸上升,或者如果进一步缩小上升将使文本不可读.

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

  • 如果我们见过面,我欠你一杯啤酒(或其他选择的饮料) - 这些东西是超级无证的,发现需要花费大量时间. (4认同)
  • 这很好用,但如果这会影响整个段落的间距而不是单行.我如何在段落中的单行上应用它? (4认同)
  • 如何调用这个方法chooseHeight? (2认同)