在字符级别更改 EditText 中的前导/行高
Change leading / line height in EditText at a character level
我在我的 EditText 的开头和结尾实现了加粗、大、不可编辑的 "smart quotes":
引号是文本中不可选择的部分,我在其上设置了RelativeSizeSpan(2f)
。结果跟我想要的差不多
s.setSpan(spanLeft, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(spanRight, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
然而,正如您所看到的,较大的字体会导致较大的高度影响整行。这在某种程度上在第一行是无关紧要的,但在最后一行却令人不快。我想知道是否有可能,对于这两个字符,保持字体大小但降低行高。
我想减少 leading 部分,以便第一行和最后一行与段落的其余部分具有一致的高度。我最大的愿望是让引语在保持其外观的同时转化为基线。
你有什么建议吗?这可能通过一些 Span
在那里吗?我该放弃吗?您看到任何解决方法了吗?
我知道我可以创建两个带有引号的 png 并使用 ImageSpan
(虽然我从未使用过它并且不知道它是如何工作的),但这对我来说有点烦人(我不是很喜欢图形)。
我在我的一个应用程序中创建了类似的效果,其中我有一个跨度,使跨度文本变小,并使其坚持主文本的 x 高度,偏离基线。我创建了一个扩展 MetricAffectingSpan
并实现基线偏移的自定义跨度。我使用 Android SDK 中的 SuperscriptSpan.java
作为示例。
本例的想法是拉低大端引用的基线,使总行高降低。我不是 100% 确定这会起作用,因为我不知道如何 "clever" 行高计算。
如果有效,请务必在多种屏幕密度下进行测试。我必须在其中某处制作 float
适合 int
,这引入了舍入误差,该误差在某些密度上非常明显,我们必须对其进行校正。
我认为您必须实施自定义 Span,只需将 updateMeasureState 留空即可:)
尝试
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
public class TestSubScriptSpan extends MetricAffectingSpan {
private final float mProportion;
public TestSubScriptSpan(float proportion) {
mProportion = proportion;
}
@Override
public void updateMeasureState(TextPaint p) {
// DO NOTHING!
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setTextSize(tp.getTextSize() * mProportion);
tp.baselineShift -= (int) (tp.ascent() / 2);
}
}
然后
TestSubScriptSpan tss = new TestSubScriptSpan(2.0f);
s.setSpan(tss, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(tss, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
注意您在 updateDrawState() 中执行的操作的顺序,因为它很重要。
我在我的 EditText 的开头和结尾实现了加粗、大、不可编辑的 "smart quotes":
引号是文本中不可选择的部分,我在其上设置了RelativeSizeSpan(2f)
。结果跟我想要的差不多
s.setSpan(spanLeft, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(spanRight, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
然而,正如您所看到的,较大的字体会导致较大的高度影响整行。这在某种程度上在第一行是无关紧要的,但在最后一行却令人不快。我想知道是否有可能,对于这两个字符,保持字体大小但降低行高。
我想减少 leading 部分,以便第一行和最后一行与段落的其余部分具有一致的高度。我最大的愿望是让引语在保持其外观的同时转化为基线。
你有什么建议吗?这可能通过一些 Span
在那里吗?我该放弃吗?您看到任何解决方法了吗?
我知道我可以创建两个带有引号的 png 并使用 ImageSpan
(虽然我从未使用过它并且不知道它是如何工作的),但这对我来说有点烦人(我不是很喜欢图形)。
我在我的一个应用程序中创建了类似的效果,其中我有一个跨度,使跨度文本变小,并使其坚持主文本的 x 高度,偏离基线。我创建了一个扩展 MetricAffectingSpan
并实现基线偏移的自定义跨度。我使用 Android SDK 中的 SuperscriptSpan.java
作为示例。
本例的想法是拉低大端引用的基线,使总行高降低。我不是 100% 确定这会起作用,因为我不知道如何 "clever" 行高计算。
如果有效,请务必在多种屏幕密度下进行测试。我必须在其中某处制作 float
适合 int
,这引入了舍入误差,该误差在某些密度上非常明显,我们必须对其进行校正。
我认为您必须实施自定义 Span,只需将 updateMeasureState 留空即可:)
尝试
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
public class TestSubScriptSpan extends MetricAffectingSpan {
private final float mProportion;
public TestSubScriptSpan(float proportion) {
mProportion = proportion;
}
@Override
public void updateMeasureState(TextPaint p) {
// DO NOTHING!
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setTextSize(tp.getTextSize() * mProportion);
tp.baselineShift -= (int) (tp.ascent() / 2);
}
}
然后
TestSubScriptSpan tss = new TestSubScriptSpan(2.0f);
s.setSpan(tss, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(tss, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
注意您在 updateDrawState() 中执行的操作的顺序,因为它很重要。