Bagaimana cara mengubah spasi huruf dalam Textview?

127

Bagaimana cara mengubah spasi huruf dalam textview? Akankah membantu jika saya memiliki teks HTML di dalamnya (saya tidak dapat menggunakan tampilan web dalam kode saya).

PS Saya menggunakan jenis huruf saya sendiri dalam tampilan teks dengan teks HTML.

OkyDokyman
sumber
5
Di editor tata letak Anda dapat melakukan android:letterSpacing=".05"Di mana .05 kira-kira "50" dalam program seperti photoshop
Jacksonkr

Jawaban:

26

lihat android: textScaleX

Bergantung pada seberapa banyak jarak yang Anda butuhkan, ini mungkin membantu. Itulah satu-satunya hal yang terkait jarak jauh dengan spasi huruf di TextView.

Sunting: silakan lihat tanggapan @ JerabekJakub di bawah ini untuk metode terbaru dan lebih baik untuk melakukan ini dimulai dengan api 21 (Lollipop)

zrgiu
sumber
9
Bagaimana Anda menerjemahkannya menjadi spasi huruf?
Eric Novins
92
Apakah ada cara untuk menambah / mengurangi spasi antar huruf / karakter? textScaleX - Sastra menskalakan huruf / karakter.
Kaymatrix
2
@Barts jawaban melakukan apa yang ditanyakan
bkurzius
2
Penskalaan teks di sumbu X bukanlah cara yang tepat untuk menangani kerning atau pelacakan di Android. Ada api untuk lollipop yang menyelesaikan ini tetapi sebelum lollipop Anda akan memerlukan tampilan teks khusus untuk melakukannya.
Elliott
2
Saya tidak tahu bagaimana solusi ini mendapat begitu banyak suara positif (+33, -24) sehingga orang-orang secara membabi buta memberikan suara mereka? letterSpacingvs textScaleXperbedaan yang sangat besar
Jimit Patel
230

Sejak API 21 ada opsi mengatur jarak huruf. Anda bisa memanggil metode setLetterSpacing atau menyetelnya dalam XML dengan atribut letterSpacing .

JerabekJakub
sumber
1
Ini tidak benar-benar berfungsi ketika diatur dalam XML. Saya mendapatkan error seperti ini:"1.2dp" in attribute "letterSpacing" cannot be converted to float."
dopatraman
20
@dopatraman Anda harus menghapus unit, ketik saja nilai: android: letterSpacing = "1.2" alih-alih android: letterSpacing = "1.2dp"
JerabekJakub
12
Mengetahui bahwa 31% perangkat tidak mendukung API 21, bagaimana Anda melakukannya di versi sebelumnya?
ninjaneer
25
Perhatikan bahwa nilai letterSpacing tidak dalam dp / sp, melainkan dalam unit 'EM'. Nilai tipikal untuk sedikit ekspansi adalah sekitar 0,05. Nilai negatif memperketat teks.
Cristan
25
Untuk beberapa alasan letterSpacingtidak berubah di pratinjau AS. Saya harus benar-benar menjalankan aplikasi di perangkat fisik untuk melihat perubahannya.
Drew Szurko
46

Lebih banyak ruang:

  android:letterSpacing="0.1"

Lebih sedikit ruang:

 android:letterSpacing="-0.07"
Pablo Cegarra
sumber
2
apa letterSpacing default?
Shivam
3
Defaultnya letterSpacingadalah 0,0 menurut developer.android.com/reference/android/widget/…
Evin1_
mungkin tambahkan komentar @ Evin1_ di jawaban Anda
Sarthak Mittal
Berapa letterSpacing maksimum dan minimum yang didukung?
Jimit Patel
26

Jawaban ini berdasarkan jawaban Pedro tetapi disesuaikan sehingga juga berfungsi jika atribut teks sudah disetel:

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

Jika Anda ingin menggunakannya secara terprogram:

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
sumber
apakah ini ditambahkan sebenarnya spasi di antara karakter? Huu ... jika seseorang menyalin teks ini, itu akan menyertakan spasi ekstra. No-Joy
johnw182
Perlu nullcheck in applyLetterSpacing, tapi selain itu, penyelamat!
Bart van Nierop
tidak berfungsi ketika Anda mengatur teks kata penutup dan kemudian menerapkan spasi secara terprogram
Jonathan
@jonney seharusnya, saya memilikinya bekerja seperti itu. Bisakah Anda mengirimkan contoh?
Bart Burg
1
Spasi tanpa jeda - "\ u00A0" - sangat berguna. Terima kasih
Shayan_Aryan
11

setelah API> = 21 ada metode inbuild yang disediakan oleh TextView yang dipanggil setLetterSpacing

periksa ini untuk lebih lanjut

Ravi
sumber
3
Bagaimana bisa sama di <21?
Rahul Devanavar
2
if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP) {this.setLetterSpacing (getResources (). getDimension (R.dimen.letter_spacing)); } lain {this.setTextScaleX (getResources (). getDimension (R.dimen.letter_spacing)); }
Maulik Patel
10

Saya membangun kelas khusus yang memperluas TextViewdan memecahkan masalah ini ... Lihat jawaban saya di sini =)

Pedro Barros
sumber
\\ terima kasih banyak telah menghemat waktu saya ^ _ ^
Muhamed El-Banna
0

Karena android tidak mendukung hal seperti itu, Anda dapat melakukannya secara manual dengan FontCreator. Ini memiliki opsi yang bagus untuk memodifikasi font. Saya menggunakan alat ini untuk membuat font khusus, meskipun membutuhkan beberapa waktu tetapi Anda selalu dapat menggunakannya dalam proyek Anda.

Ali
sumber