Comment changer l'espacement des lettres dans une vue textuelle?


127

Comment modifier l'espacement des lettres dans une vue de texte? Cela aidera-t-il si j'ai du texte HTML (je ne peux pas utiliser la vue Web dans mon code).

PS J'utilise ma propre police de caractères dans la vue de texte avec du texte HTML.


5
Dans l'éditeur de mise en page, vous pouvez faire android:letterSpacing=".05"Où .05 serait à peu près "50" dans un programme comme Photoshop
Jacksonkr

Réponses:


26

consultez android: textScaleX

En fonction de l'espacement dont vous avez besoin, cela peut vous aider. C'est la seule chose liée à distance à l'espacement des lettres dans TextView.

Edit: veuillez voir la réponse de @ JerabekJakub ci-dessous pour une meilleure méthode mise à jour pour le faire en commençant par api 21 (Lollipop)


9
Comment traduiriez-vous cela en espacement des lettres?
Eric Novins

92
Existe-t-il un moyen d'augmenter / diminuer l'espace entre les lettres / caractères? textScaleX - Literary met à l'échelle les lettres / caractères.
Kaymatrix

2
@Barts answer fait ce que la question demande
bkurzius

2
La mise à l'échelle du texte sur l'axe X n'est pas la bonne façon de gérer le crénage ou le suivi dans Android. Il existe une API pour Lollipop qui accomplit cela, mais avant de Lollipop, vous aurez besoin d'une vue de texte personnalisée pour ce faire.
Elliott

2
Je ne sais pas comment cette solution a obtenu autant de votes positifs (+33, -24) est-ce que les gens votent aveuglément? letterSpacingvs textScaleXquelle énorme différence
Jimit Patel

230

Depuis l'API 21, il existe une option d'espacement des lettres. Vous pouvez appeler la méthode setLetterSpacing ou la définir en XML avec l'attribut letterSpacing .


1
Cela ne fonctionne pas réellement lorsqu'il est défini dans le XML. "1.2dp" in attribute "letterSpacing" cannot be converted to float."
J'obtiens

20
@dopatraman Vous devez omettre les unités, tapez simplement la valeur: android: letterSpacing = "1.2" au lieu de android: letterSpacing = "1.2dp"
JerabekJakub

12
Sachant que 31% des appareils ne prennent pas en charge l'API 21, comment feriez-vous cela dans les versions précédentes?
ninjaneer

25
Notez que la valeur de letterSpacing n'est pas en dp / sp, elle est en unités «EM». Les valeurs typiques pour une légère expansion seront d'environ 0,05. Les valeurs négatives resserrent le texte.
Cristan

25
Pour une raison quelconque letterSpacing, cela ne changeait pas dans l'aperçu AS. J'ai dû exécuter l'application sur un appareil physique pour voir le changement.
Drew Szurko


26

Cette réponse est basée sur la réponse de Pedro mais ajustée afin qu'elle fonctionne également si l'attribut de texte est déjà défini:

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

Si vous souhaitez l'utiliser par programme:

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

cela ajoute-t-il réellement des espaces entre les caractères? Boo ... si quelqu'un copie ce texte, il inclura les espaces supplémentaires. No-Joy
johnw182

Besoin d'un nullenregistrement applyLetterSpacing, mais à part ça, la vie sauve!
Bart van Nierop

ne fonctionne pas lorsque vous définissez le texte après les mots, puis appliquez l'espacement par programme
Jonathan

@jonney ça devrait, je le fais fonctionner comme ça. Pouvez-vous envoyer un exemple?
Bart Burg

1
L'espace sans interruption - "\ u00A0" - est vraiment utile. Merci
Shayan_Aryan

11

après API> = 21, il existe une méthode inbuild fournie par TextView appelée setLetterSpacing

vérifiez ceci pour plus


3
Comment pouvez-vous faire la même chose en <21?
Rahul Devanavar

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

Comme Android ne prend pas en charge une telle chose, vous pouvez le faire manuellement avec FontCreator. Il a de bonnes options pour modifier la police. J'ai utilisé cet outil pour créer une police personnalisée, même si cela prend du temps, mais vous pouvez toujours l'utiliser dans vos projets.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.