Jak zmienić odstępy między literami w widoku tekstowym?


127

Jak mogę zmienić odstępy między literami w widoku tekstu? Czy to pomoże, jeśli mam w nim tekst HTML (nie mogę użyć webview w moim kodzie).

PS Używam własnego kroju w widoku tekstowym z tekstem HTML.


5
W edytorze układu możesz zrobić android:letterSpacing=".05"Gdzie .05 byłoby mniej więcej „50” w programie takim jak Photoshop
Jacksonkr

Odpowiedzi:


26

sprawdź android: textScaleX

W zależności od potrzebnych odstępów może to pomóc. To jedyna rzecz, która jest zdalnie związana z odstępami między literami w TextView.

Edycja: zobacz odpowiedź @ JerabekJakub poniżej, aby uzyskać zaktualizowaną, lepszą metodę, aby to zrobić, zaczynając od api 21 (Lollipop)


9
Jak przełożyłbyś to na odstępy między literami?
Eric Novins

92
Czy istnieje sposób na zwiększenie / zmniejszenie odstępu między literami / znakami? textScaleX - Literackie skaluje litery / znaki.
Kaymatrix

2
@Barts odpowiada na pytanie
bkurzius

2
Skalowanie tekstu na osi X nie jest właściwym sposobem obsługi kerningu lub śledzenia w systemie Android. Istnieje interfejs API dla Lollipopa, który to robi, jednak przed Lollipopem będziesz potrzebować niestandardowego widoku tekstu, aby to osiągnąć.
Elliott,

2
Nie wiem, jak to rozwiązanie zyskało tak wiele głosów za (+33, -24), czy ludzie po prostu ślepo oddają swoje głosy? letterSpacingvs textScaleXjaka ogromna różnica
Jimit Patel

230

Od API 21 istnieje możliwość ustawienia odstępów między literami. Możesz wywołać metodę setLetterSpacing lub ustawić ją w XML z atrybutem letterSpacing .


1
To faktycznie nie działa, gdy jest ustawione w XML. Otrzymuję taki błąd:"1.2dp" in attribute "letterSpacing" cannot be converted to float."
dopatraman

20
@dopatraman Musisz ominąć jednostki, wpisz po prostu wartość: android: letterSpacing = "1.2" zamiast android: letterSpacing = "1.2dp"
JerabekJakub

12
Wiedząc, że 31% urządzeń nie obsługuje API 21, jak byś to zrobił w poprzednich wersjach?
ninjaneer

25
Zwróć uwagę, że wartość odstępu między literami nie jest wyrażona w dp / sp, ale w jednostkach „EM”. Typowe wartości dla niewielkiego rozszerzenia będą wynosić około 0,05. Wartości ujemne zawężają tekst.
Cristan,

25
Z jakiegoś powodu letterSpacingnie zmienia się w podglądzie AS. Musiałem faktycznie uruchomić aplikację na urządzeniu fizycznym, aby zobaczyć zmianę.
Drew Szurko


26

Ta odpowiedź jest oparta na odpowiedzi Pedro, ale została dostosowana, więc działa również, jeśli atrybut tekstu jest już ustawiony:

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

Jeśli chcesz używać go programowo:

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

czy to jest faktycznie dodane spacje między znakami? Boo ... jeśli ktoś skopiuje ten tekst, będzie zawierał dodatkowe spacje. No-Joy
johnw182

Potrzebuje nullzameldowania applyLetterSpacing, ale poza tym ratuje życie!
Bart van Nierop

nie działa, gdy ustawisz tekst po słowie, a następnie programowo zastosujesz odstępy
Jonathan

@jonney powinno, mam to tak działające. Czy mógłbyś podać przykład?
Bart Burg

1
Przestrzeń bez przerwy - „\ u00A0” - jest naprawdę przydatna. Dzięki
Shayan_Aryan,

11

po API> = 21 istnieje metoda wbudowana dostarczana przez TextView o nazwie setLetterSpacing

sprawdź to po więcej


3
Jak to samo w <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

Ponieważ Android nie obsługuje czegoś takiego, możesz to zrobić ręcznie za pomocą FontCreator. Ma dobre opcje modyfikowania czcionek. Użyłem tego narzędzia do zbudowania niestandardowej czcionki, nawet jeśli zajmuje to trochę czasu, ale zawsze możesz jej użyć w swoich projektach.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.