Wie ändere ich den Buchstabenabstand in einer Textansicht?

127

Wie kann ich den Buchstabenabstand in einer Textansicht ändern? Hilft es, wenn ich HTML-Text darin habe (ich kann Webview nicht in meinem Code verwenden).

PS Ich verwende meine eigene Schrift in der Textansicht mit HTML-Text.

OkyDokyman
quelle
5
Im Layout-Editor können Sie tun, android:letterSpacing=".05"wo
.05

Antworten:

26

check out android: textScaleX

Je nachdem, wie viel Abstand Sie benötigen, kann dies hilfreich sein. Dies ist das einzige, was im Zusammenhang mit dem Buchstabenabstand in der Textansicht steht.

Edit: siehe @ JerabekJakub Antwort unten für eine aktualisierte, bessere Methode , dies mit 21 api beginnen zu tun (Lollipop)

zrgiu
quelle
9
Wie würden Sie das in Buchstabenabstände übersetzen?
Eric Novins
92
Gibt es eine Möglichkeit, den Abstand zwischen Buchstaben / Zeichen zu vergrößern / verkleinern? textScaleX - Literarisch skaliert die Buchstaben / Zeichen.
Kaymatrix
2
@Barts Antwort macht, was die Frage stellt
bkurzius
2
Das Skalieren des Texts auf der X-Achse ist nicht die richtige Methode, um Kerning oder Tracking in Android zu handhaben. Es gibt eine API für Lollipop, die dies ermöglicht. Vor Lollipop benötigen Sie jedoch eine benutzerdefinierte Textansicht, um dies zu erreichen.
Elliott
2
Ich weiß nicht, wie diese Lösung so viele positive Stimmen erhalten hat (+33, -24). Geben die Leute nur blind ihre Stimmen ab? letterSpacingvs textScaleXwas für ein großer Unterschied
Jimit Patel
230

Seit API 21 gibt es eine Option zum Festlegen des Buchstabenabstands. Sie können die Methode setLetterSpacing aufrufen oder in XML mit dem Attribut letterSpacing festlegen .

JerabekJakub
quelle
1
Dies funktioniert nicht wirklich, wenn es im XML festgelegt ist. Ich erhalte eine Fehlermeldung wie "1.2dp" in attribute "letterSpacing" cannot be converted to float."
folgt
20
@dopatraman Sie müssen Einheiten auslassen, geben Sie nur Wert ein: android: letterSpacing = "1.2" anstelle von android: letterSpacing = "1.2dp"
JerabekJakub
12
Wie würden Sie dies in früheren Versionen tun, wenn Sie wissen, dass 31% der Geräte API 21 nicht unterstützen?
Ninjaneer
25
Beachten Sie, dass der Wert von letterSpacing nicht in dp / sp, sondern in 'EM'-Einheiten angegeben ist. Typische Werte für eine leichte Expansion liegen bei etwa 0,05. Negative Werte verschärfen den Text.
Cristan
25
Aus irgendeinem Grund letterSpacingänderte sich nichts in der AS-Vorschau. Ich musste die App tatsächlich auf einem physischen Gerät ausführen, um die Änderung zu sehen.
Drew Szurko
46

Mehr Platz:

  android:letterSpacing="0.1"

Wenig Platz:

 android:letterSpacing="-0.07"
Pablo Cegarra
quelle
2
Was ist der Standard-LetterSpacing?
Shivam
3
Der Standardwert letterSpacingist 0.0 laut developer.android.com/reference/android/widget/…
Evin1_
Vielleicht füge @ Evin1_s Kommentar in
deine
Was ist der maximale und minimale LetterSpacing, der unterstützt wird?
Jimit Patel
26

Diese Antwort basiert auf Pedros Antwort, wurde jedoch angepasst, sodass sie auch funktioniert, wenn das Textattribut bereits festgelegt ist:

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

Wenn Sie es programmgesteuert verwenden möchten:

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
quelle
Ist dies tatsächlich Leerzeichen zwischen den Zeichen hinzugefügt? Boo ... wenn jemand diesen Text kopiert, enthält er die zusätzlichen Leerzeichen. No-Joy
Johnw182
Benötigt einen nullCheck-in applyLetterSpacing, aber ansonsten Lebensretter!
Bart van Nierop
funktioniert nicht, wenn Sie die Textnachwörter setzen und dann den Abstand programmgesteuert anwenden
Jonathan
@jonney sollte es, ich habe es so arbeiten. Könnten Sie ein Beispiel senden?
Bart Burg
1
Der No-Break-Bereich - "\ u00A0" - ist wirklich nützlich. Danke
Shayan_Aryan
11

Nach API> = 21 wird die von TextView bereitgestellte Inbuild-Methode aufgerufen setLetterSpacing

Überprüfen Sie dies für mehr

Ravi
quelle
3
Wie kann man das in <21 gleich machen?
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

Ich habe eine benutzerdefinierte Klasse erstellt, TextViewdie dieses Problem erweitert und löst ... Überprüfen Sie meine Antwort hier =)

Pedro Barros
quelle
\\ vielen Dank für die Zeitersparnis ^ _ ^
Muhamed El-Banna
0

Da Android so etwas nicht unterstützt, können Sie es manuell mit FontCreator tun. Es bietet gute Optionen zum Ändern von Schriftarten. Ich habe dieses Tool verwendet, um eine benutzerdefinierte Schriftart zu erstellen, auch wenn dies einige Zeit in Anspruch nimmt, aber Sie können sie jederzeit in Ihren Projekten verwenden.

Ali
quelle