Como alterar o espaçamento entre letras em um Textview?


127

Como posso alterar o espaçamento entre letras em uma visualização de texto? Ajudará se eu tiver texto HTML (não consigo usar a visualização da web no meu código).

PS Estou usando meu próprio tipo de letra na visualização de texto com texto HTML.


5
No editor de layout, você pode fazer android:letterSpacing=".05"Where .05 seria aproximadamente "50" em um programa como o photoshop
Jacksonkr

Respostas:


26

confira android: textScaleX

Dependendo do espaçamento necessário, isso pode ajudar. Essa é a única coisa remotamente relacionada ao espaçamento entre letras no TextView.

Editar: consulte a resposta de @ JerabekJakub abaixo para obter um método melhor e atualizado para fazer isso, começando com a api 21 (pirulito)


9
Como você traduziria isso para espaçamento entre letras?
Eric Novins

92
Existe uma maneira de aumentar / diminuir o espaço entre letras / caracteres? textScaleX - Literário dimensiona as letras / caracteres.
Kaymatrix

2
@Barts resposta faz o que a questão está pedindo
bkurzius

2
Escalar o texto no eixo X não é a maneira correta de lidar com kerning ou rastreamento no Android. Existe uma API para pirulito que realiza isso, porém, anterior ao pirulito, você precisará de uma visualização de texto personalizada para fazer isso.
Elliott

2
Não sei como essa solução recebeu tantos votos positivos (+33, -24) que as pessoas estão apenas cegamente votando? letterSpacingvs textScaleXo que uma enorme diferença
Jimit Patel

230

Desde a API 21, existe um espaçamento entre letras do conjunto de opções. Você pode chamar o método setLetterSpacing ou configurá-lo em XML com o atributo letterSpacing .


1
Na verdade, isso não funciona quando definido no XML. Eu recebo um erro como este:"1.2dp" in attribute "letterSpacing" cannot be converted to float."
dopatraman 16/01

20
@dopatraman Você tem que omitir unidades, digite apenas o valor: android: letterSpacing = "1.2" em vez de android: letterSpacing = "1.2dp"
JerabekJakub

12
Sabendo que 31% dos dispositivos não oferecem suporte à API 21, como você faria isso nas versões anteriores?
Ninjaneer 2/16

25
Observe que o valor de letterSpacing não está em dp / sp, está em unidades 'EM'. Os valores típicos para leve expansão serão em torno de 0,05. Valores negativos restringem o texto.
Cristan

25
Por algum motivo letterSpacingnão estava mudando na visualização do AS. Eu tive que realmente executar o aplicativo em um dispositivo físico para ver a mudança.
Tirou Szurko


26

Esta resposta é baseada na resposta de Pedro, mas ajustada para que também funcione se o atributo de texto já estiver definido:

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() {
        if (this == null || this.originalText == null) return;
        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;
    }
}

Se você deseja usá-lo programaticamente:

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

isso é adicionado, na verdade, espaços entre os caracteres? Boo ... se alguém copiar esse texto, ele incluirá os espaços extras. No-Joy
johnw182

Precisa de um nullcheck-in applyLetterSpacing, mas fora isso, salva-vidas!
Bart van Nierop

não funciona quando u definir os afterwords de texto e depois aplicar espaçamento programaticamente
Jonathan

@ Jonney deveria, eu tenho que trabalhar assim. Você poderia enviar um exemplo?
Bart Burg

1
O espaço sem interrupção - "\ u00A0" - é realmente útil. Graças
Shayan_Aryan

11

depois da API> = 21, existe o método inbuild fornecido pelo TextView chamado setLetterSpacing

verifique isso para mais


3
Como pode o mesmo em <21?
Rahul Devanavar 01/03/19

2
if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP) {this.setLetterSpacing (getResources (). getDimension (R.dimen.letter_spacing)); } else {this.setTextScaleX (getResources (). getDimension (R.dimen.letter_spacing)); }
Maulik Patel


0

Como o Android não suporta isso, você pode fazê-lo manualmente com o FontCreator. Tem boas opções para modificar fontes. Usei essa ferramenta para criar uma fonte personalizada, mesmo que demore algum tempo, mas você sempre pode usá-la em seus projetos.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.