Come modificare la spaziatura delle lettere in una visualizzazione di testo?


127

Come posso modificare la spaziatura delle lettere in una visualizzazione di testo? Sarà utile se ho testo HTML in esso (non posso usare webview nel mio codice).

PS Sto usando il mio carattere tipografico nella visualizzazione testo con testo HTML.


5
Nell'editor di layout puoi fare android:letterSpacing=".05"Dove .05 sarebbe all'incirca "50" in un programma come Photoshop
Jacksonkr

Risposte:


26

controlla Android: textScaleX

A seconda della spaziatura necessaria, questo potrebbe essere d'aiuto. Questa è l'unica cosa collegata in remoto alla spaziatura delle lettere nel TextView.

Modifica: vedere la risposta di @ JerabekJakub di seguito per un metodo aggiornato e migliore per farlo a partire da api 21 (Lollipop)


9
Come lo traduresti nella spaziatura delle lettere?
Eric Novins

92
C'è un modo per aumentare / diminuire lo spazio tra lettere / caratteri? textScaleX - Letterario scala le lettere / caratteri.
Kaymatrix

2
La risposta di @Barts fa quello che la domanda sta chiedendo
bkurzius

2
Il ridimensionamento del testo sull'asse X non è il modo corretto per gestire la crenatura o il tracciamento in Android. Esiste un'API per lollipop che esegue questa operazione, tuttavia prima di lollipop avrai bisogno di una visualizzazione di testo personalizzata per farlo.
Elliott

2
Non so come questa soluzione abbia ottenuto così tanti voti positivi (+33, -24) le persone stanno semplicemente votando ciecamente? letterSpacingvs textScaleXche differenza enorme
Jimit Patel

230

Dall'API 21 esiste un'opzione per impostare la spaziatura delle lettere. Puoi chiamare il metodo setLetterSpacing o impostarlo in XML con l'attributo letterSpacing .


1
Questo in realtà non funziona se impostato nell'XML. Ricevo un errore come questo:"1.2dp" in attribute "letterSpacing" cannot be converted to float."
dopatraman

20
@dopatraman Devi omettere le unità, digita solo il valore: android: letterSpacing = "1.2" invece di android: letterSpacing = "1.2dp"
JerabekJakub

12
Sapendo che il 31% dei dispositivi non supporta l'API 21, come lo faresti nelle versioni precedenti?
ninjaneer

25
Nota che il valore di letterSpacing non è in dp / sp, è in unità "EM". I valori tipici per una leggera espansione saranno intorno a 0,05. I valori negativi rafforzano il testo.
Cristan

25
Per qualche motivo letterSpacingnon stava cambiando nell'anteprima AS. Ho dovuto eseguire effettivamente l'app su un dispositivo fisico per vedere il cambiamento.
Drew Szurko


26

Questa risposta è basata sulla risposta di Pedro ma modificata in modo che funzioni anche se l'attributo di testo è già impostato:

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

Se vuoi usarlo in modo programmatico:

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

è questo aggiunto effettivamente spazi tra i personaggi? Boo ... se qualcuno copia questo testo includerà gli spazi extra. No-Joy
johnw182

Ha bisogno di un nullcheck-in applyLetterSpacing, ma a parte questo, salvavita!
Bart van Nierop

non funziona quando si impostano le parole successive del testo e quindi si applica la spaziatura in modo programmatico
Jonathan

@jonney dovrebbe, ho funzionato così. Potresti mandare un esempio?
Bart Burg

1
Lo spazio no-break - "\ u00A0" - è davvero utile. Grazie
Shayan_Aryan

11

dopo API> = 21 c'è un metodo integrato fornito da TextView chiamato setLetterSpacing

controlla questo per ulteriori informazioni


3
Come si può fare lo stesso in <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

Ho creato una classe personalizzata che estende TextViewe risolve questo problema ... Controlla la mia risposta qui =)


\\ grazie mille per avermi risparmiato tempo ^ _ ^
Muhamed El-Banna

0

Poiché Android non supporta una cosa del genere, puoi farlo manualmente con FontCreator. Ha buone opzioni per la modifica dei caratteri. Ho usato questo strumento per costruire un font personalizzato, anche se ci vuole del tempo ma puoi sempre usarlo nei tuoi progetti.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.