How to adjust text kerning in Android TextView?

后端 未结 12 1571
醉话见心
醉话见心 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:50

    It's difficult to adjust spacing between characters, when you are using TextView. But if you can handle the drawing yourself, there should be some way to do that.

    My answer to this question is: use your custom Span .

    My code:

    public class LetterSpacingSpan extends ReplacementSpan {
        private int letterSpacing = 0;
    
        public LetterSpacingSpan spacing(int space) {
            letterSpacing = space;
    
            return this;
        }
    
    
        @Override
        public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
            return (int) paint.measureText(text, start, end) + (text.length() - 1) * letterSpacing;
        }
    
    
        @Override
        public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
            int length = text.length();
            float currentX = x;
    
            for (int i = 1; i < length; i++) {          
                canvas.drawText(text, i, i + 1, currentX, y, paint);
                currentX += paint.measureText(text, i, i + 1) + letterSpacing;
             }
        }
    }
    

    Explain:

    Building your own Span can help you achieve many amazing effect, like make a blur TextView, change the background or foreground for your TextView, even make some animation. I learn a lot from this post Span a powerful concept .

    Because you are adding spacing to each character, so we should use a character level base span, in this case, ReplacementSpan is the best choice. I add a spacing method, so when using it, you can simply pass the space you want for each character as parameter.

    When building your custom span, you need to override at least two method, getSize and draw. The getSize method should return the final width after we add the spacing for the whole charsequence, and inside the draw method block, you can control the Canvas to do the drawing you want.

    So how we use this LetterSpacingSpan? It's easy:

    Usage:

    TextView textView;
    Spannable content = new SpannableString("This is the content");
    textView.setSpan(new LetterSpacingSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(content);
    

    And that's it.

提交回复
热议问题