如何在Android TextView中调整文本字距调整?

emm*_*mby 26 android spacing textview kerning

有没有办法调整Android中的字符间距TextView?我相信这通常被称为"字距调整".

我知道android:textScaleX属性,但是压缩字符和间距.

Ped*_*ros 68

我构建了一个扩展TextView的自定义类,并添加了一个方法"setSpacing".解决方法类似于@Noah所说的.该方法在String的每个字母之间添加一个空格,并使用SpannedString更改空格的TextScaleX,允许正负间距.

希望能帮助某人^^

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

使用它:

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

  • 如果有人试图使用它,那么只需要提醒.如果你将android:textAllCaps设置为true,它将删除跨度上的宽度并导致它无法正确呈现 (6认同)
  • 用无中断空间builder.append("\ u00A0")替换builder.append("")解决了这个问题.谢谢你的代码! (5认同)

Tak*_*ion 14

如果有人正在寻找一种简单的方法将字距调整应用于任何字符串(技术上CharSequence),而不使用TextView:

public static Spannable applyKerning(CharSequence src, float kerning)
{
    if (src == null) return null;
    final int srcLength = src.length();
    if (srcLength < 2) return src instanceof Spannable
                              ? (Spannable)src
                              : new SpannableString(src);

    final String nonBreakingSpace = "\u00A0";
    final SpannableStringBuilder builder = src instanceof SpannableStringBuilder
                                           ? (SpannableStringBuilder)src
                                           : new SpannableStringBuilder(src);
    for (int i = src.length() - 1; i >= 1; i--)
    {
        builder.insert(i, nonBreakingSpace);
        builder.setSpan(new ScaleXSpan(kerning), i, i + 1,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return builder;
}
Run Code Online (Sandbox Code Playgroud)


Com*_*are 12

AFAIK,你不能调整字距TextView.如果您Canvas使用2D图形API 在自己上绘制文本,则可以调整字距调整.

  • @CommonsWare自API21以来,'letterSpacing'也是如此.但是向后兼容呢?我正在研究库`v7`的样式,但似乎不支持它.你能告诉我们你的发现吗? (2认同)
  • 不再正确:请查看 `android:letterSpacing` https://developer.android.com/reference/android/widget/TextView#attr_android:letterSpacing (2认同)

Alg*_*gar 7

从Android 21开始,您可以使用设置letterSpacing属性。

<TextView
    android:width="..."
    android:height="..."
    android:letterSpacing="1.3"/>
Run Code Online (Sandbox Code Playgroud)