在字符级别更改 EditText 中的前导/行高

nat*_*rio 5 android android-layout android-edittext spannablestring

我在 EditText 的开头和结尾实施了粗体、大、不可编辑的“智能引号”:

在此处输入图片说明

引号是文本的不可选择部分,我在其上设置了RelativeSizeSpan(2f). 结果几乎是我想要的。

s.setSpan(spanLeft, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(spanRight, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Run Code Online (Sandbox Code Playgroud)

但是,正如您所看到的,更大的字体会导致更大的高度,从而影响整行。这在第一行是无关紧要的,但在最后一行却令人不快。我想知道这两个字符是否有可能保持字体大小但降低行高。

在此处输入图片说明

我想减少前导部分,以便第一行和最后一行与段落的其余部分具有一致的高度。我最大的愿望是将引号转换为基线,同时保持其外观。

你有什么建议吗?这是可能的Span吗?我应该放弃吗?你看到任何解决方法吗?

我看到我可以用引号创建两个 png 并使用ImageSpan(虽然我从未使用过它并且不知道它是如何工作的),但这对我来说有点烦人(我不是很喜欢图形)。

Mim*_*oli 1

我相信您必须实现自定义 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

进而

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);
Run Code Online (Sandbox Code Playgroud)

请注意 updateDrawState() 中执行操作的顺序,因为它很重要。