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.

OkyDokyman
la source
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)

zrgiu
la source
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 .

JerabekJakub
la source
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
46

Plus d'espace:

  android:letterSpacing="0.1"

Moins d'espace:

 android:letterSpacing="-0.07"
Pablo Cegarra
la source
2
quelle est la letterSpacing par défaut?
Shivam
3
La valeur par défaut letterSpacingest 0.0 selon developer.android.com/reference/android/widget/…
Evin1_
peut-être ajouter le commentaire de @ Evin1_ dans votre réponse
Sarthak Mittal
quel est le letterSpacing maximum et minimum pris en charge?
Jimit Patel le
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);
Bart Burg
la source
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

Ravi
la source
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
10

J'ai construit une classe personnalisée qui étend TextViewet résout ce problème ... Découvrez ma réponse ici =)

Pedro Barros
la source
\\ merci beaucoup pour gagner mon temps ^ _ ^
Muhamed El-Banna le
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.

Ali
la source