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.


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)


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 .


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


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

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


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


\\ 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.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.