Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change text kerning or spacing in TextView?

Tags:

android

I have a requirement where the letters in a TextView need to be spaced a little farther apart. Unfortunately, most of the resources I find seem to say this cannot be done--at least not easily.

So far, the apparent solutions are:

  1. Add spaces in between the characters in the String-- "A B C" instead of "ABC". Of course, that doesn't work if only a LITTLE more space is needed.
  2. Change textScale, but that affects the size of the letters, not just the spacing between letters
  3. Use the Font class, but that isn't available until Honeycomb (I need something Gingerbread compatible) and it has been deprecated in JellyBean, so that's not a good option.
  4. Find a font with different kerning, but that's not practiif clients want to use the same font.
  5. Override onDraw for a View, drawing characters to the Canvas one character at a time, manually specifying exactly where each character should be drawn.

Is there something I'm missing? It seems like there should be a better way. I see TextAttribute.KERNING and TextAttribute.TRACKING... it seems like those should be able to be used easily, but I can't figure out how.

What's the best way to change the spacing between letters in a TextView?

like image 864
Chad Schultz Avatar asked Jan 14 '23 13:01

Chad Schultz


2 Answers

The solution I found is to mix the solutions 1 and 2 that you described. Adding spaces between letters and than changing the TextScaleX only of the spaces, so you keep other characters the same. I built a custom class that extends TextView and allows you to define the letter spacing. Everything else is automatic =)

I posted the class on this other answer

Hope that helps ^^

like image 127
Pedro Barros Avatar answered Jan 24 '23 15:01

Pedro Barros


This answer is based on Pedro's answer but editted so it also works when text attribute is allready set:

package nl.raakict.android.spc.widget;
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ScaleXSpan;
import android.util.AttributeSet;
import android.widget.TextView;


public class LetterSpacingTextView extends TextView {
    private float letterSpacing = LetterSpacing.BIGGEST;
    private CharSequence originalText = "";


    public LetterSpacingTextView(Context context) {
        super(context);
    }

    public LetterSpacingTextView(Context context, AttributeSet attrs){
        super(context, attrs);
        originalText = super.getText();
        applyLetterSpacing();
        this.invalidate();
    }

    public LetterSpacingTextView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
    }

    public float getLetterSpacing() {
        return letterSpacing;
    }

    public void setLetterSpacing(float letterSpacing) {
        this.letterSpacing = letterSpacing;
        applyLetterSpacing();
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        originalText = text;
        applyLetterSpacing();
    }

    @Override
    public CharSequence getText() {
        return originalText;
    }

    private void applyLetterSpacing() {
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < originalText.length(); i++) {
            String c = ""+ originalText.charAt(i);
            builder.append(c.toLowerCase());
            if(i+1 < originalText.length()) {
                builder.append("\u00A0");
            }
        }
        SpannableString finalText = new SpannableString(builder.toString());
        if(builder.toString().length() > 1) {
            for(int i = 1; i < builder.toString().length(); i+=2) {
                finalText.setSpan(new ScaleXSpan((letterSpacing+1)/10), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        super.setText(finalText, BufferType.SPANNABLE);
    }

    public class LetterSpacing {
        public final static float NORMAL = 0;
        public final static float NORMALBIG = (float)0.025;
        public final static float BIG = (float)0.05;
        public final static float BIGGEST = (float)0.2;
    }
}
like image 43
Bart Burg Avatar answered Jan 24 '23 13:01

Bart Burg