Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change leading / line height in EditText at a character level

I have implemented bold, big, non-editable "smart quotes" at the start and the end of my EditText:

enter image description here

Quotes are a non-selectable part of the text, on which I set a RelativeSizeSpan(2f). The result is pretty much what I wanted.

s.setSpan(spanLeft, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(spanRight, s.length() - 1, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

However as you can see having a bigger font size results in a bigger height that affects the whole line. This is somehow irrelevant on the very first line, but displeasing on the very last. I was wondering if it is possible, for those two characters, to keep the font size but reduce the line height.

enter image description here

I want to reduce the leading part, so that first and last line have a consistent height with the rest of the paragraph. My highest desire would be for the quotes to kind of translate to the baseline while keeping their appearance.

Do you have any suggestion? Is this possible through some Span out there? Should I give up? Do you see any workaround?

I see I could create two pngs with the quotes and use ImageSpan (though I never used it and don't know how that would work), but it's kind of annoying for me (I'm not really into graphics).

like image 297
natario Avatar asked Nov 10 '22 08:11

natario


1 Answers

I believe that you have to implement your custom Span, just leaving the updateMeasureState empty :)
Try with

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

and then

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

Pay attention to the order of what you do inside the updateDrawState(), since it's important.

like image 198
Mimmo Grottoli Avatar answered Nov 14 '22 22:11

Mimmo Grottoli