How to adjust text kerning in Android TextView?

后端 未结 12 1570
醉话见心
醉话见心 2020-11-30 20:20

Is there a way to adjust the spacing between characters in an Android TextView? I believe this is typically called \"kerning\".

I\'m aware of the

12条回答
  •  借酒劲吻你
    2020-11-30 20:59

    I built a custom class that extends TextView and adds a method "setSpacing". The workaround is similar to what @Noah said. The method adds a space between each letter of the String and with SpannedString changes the TextScaleX of the spaces, allowing positive and negative spacing.

    Hope that helps someone ^^

    /**
     * Text view that allows changing the letter spacing of the text.
     * 
     * @author Pedro Barros (pedrobarros.dev at gmail.com)
     * @since May 7, 2013
     */
    
    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 spacing = Spacing.NORMAL;
        private CharSequence originalText = "";
    
    
        public LetterSpacingTextView(Context context) {
            super(context);
        }
    
        public LetterSpacingTextView(Context context, AttributeSet attrs){
            super(context, attrs);
        }
    
        public LetterSpacingTextView(Context context, AttributeSet attrs, int defStyle){
            super(context, attrs, defStyle);
        }
    
        public float getSpacing() {
            return this.spacing;
        }
    
        public void setSpacing(float spacing) {
            this.spacing = spacing;
            applySpacing();
        }
    
        @Override
        public void setText(CharSequence text, BufferType type) {
            originalText = text;
            applySpacing();
        }
    
        @Override
        public CharSequence getText() {
            return originalText;
        }
    
        private void applySpacing() {
            if (this == null || this.originalText == null) return;
            StringBuilder builder = new StringBuilder();
            for(int i = 0; i < originalText.length(); i++) {
                builder.append(originalText.charAt(i));
                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((spacing+1)/10), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
            super.setText(finalText, BufferType.SPANNABLE);
        }
    
        public class Spacing {
            public final static float NORMAL = 0;
        }
    }
    

    Using it:

    LetterSpacingTextView textView = new LetterSpacingTextView(context);
    textView.setSpacing(10); //Or any float. To reset to normal, use 0 or LetterSpacingTextView.Spacing.NORMAL
    textView.setText("My text");
    //Add the textView in a layout, for instance:
    ((LinearLayout) findViewById(R.id.myLinearLayout)).addView(textView);
    

提交回复
热议问题