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 可跨行高的主要内容,如果未能解决你的问题,请参考以下文章
支持 RTL 语言的 Android Justify 可跨文本视图
Android Calendar Provider:是不是有可跨多个设备使用的事件唯一标识符?