Как изменить интервал между буквами в Textview?

127

Как изменить межбуквенный интервал в текстовом окне? Поможет ли это, если у меня будет HTML-текст (я не могу использовать веб-просмотр в своем коде).

PS Я использую свой собственный шрифт в текстовом представлении с текстом HTML.

OkyDokyman
источник
5
В редакторе макетов вы можете сделать android:letterSpacing=".05"Где .05 будет примерно «50» в программе, такой как Photoshop
Jacksonkr

Ответы:

26

проверить android: textScaleX

В зависимости от того, какой интервал вам нужен, это может помочь. Это единственное, что удаленно связано с межбуквенным интервалом в TextView.

Изменить: см. Ответ @ JerabekJakub ниже, чтобы узнать об обновленном, лучшем способе сделать это, начиная с api 21 (Lollipop)

zrgiu
источник
9
Как бы вы перевели это на межбуквенный интервал?
Эрик Новинс
92
Есть ли способ увеличить / уменьшить расстояние между буквами / символами? textScaleX - Литературное масштабирование букв / символов.
Kaymatrix
2
Ответ @Barts выполняет то, что задает вопрос
bkurzius
2
Масштабирование текста по оси X - неправильный способ обработки кернинга или отслеживания в Android. Для этого существует API-интерфейс для леденца на палочке, однако до версии Lollipop для этого вам понадобится настраиваемое текстовое представление.
Elliott
2
Я не знаю, как это решение получило столько голосов (+33, -24), что люди просто слепо голосуют? letterSpacingи textScaleXкакая огромная разница
Джимит Патель
230

Начиная с API 21 существует возможность установки межбуквенного интервала. Вы можете вызвать метод setLetterSpacing или установить его в XML с атрибутом letterSpacing .

JerabekJakub
источник
1
На самом деле это не работает, если установлено в XML. Я получаю такую ​​ошибку:"1.2dp" in attribute "letterSpacing" cannot be converted to float."
dopatraman
20
@dopatraman Вы должны опускать единицы измерения, введите просто значение: android: letterSpacing = "1.2" вместо android: letterSpacing = "1.2dp"
JerabekJakub
12
Зная, что 31% устройств не поддерживают API 21, как бы вы это сделали в предыдущих версиях?
ninjaneer 02
25
Обратите внимание, что значение letterSpacing не в dp / sp, а в единицах EM. Типичные значения для небольшого расширения будут около 0,05. Отрицательные значения сужают текст.
Кристан
25
По какой-то причине letterSpacingне менялось в предварительном просмотре AS. Мне пришлось запустить приложение на физическом устройстве, чтобы увидеть изменения.
Дрю Шурко
46

Больше пространства:

  android:letterSpacing="0.1"

Меньше места:

 android:letterSpacing="-0.07"
Пабло Сегарра
источник
2
какой по умолчанию letterSpacing?
Шивы
3
По умолчанию letterSpacing0.0 согласно developer.android.com/reference/android/widget/…
Evin1_
возможно, добавьте комментарий @ Evin1_ в свой ответ
Сартак Миттал
Какое максимальное и минимальное расстояние между буквами поддерживается?
Джимит Патель,
26

Этот ответ основан на ответе Педро, но настроен так, чтобы он также работал, если текстовый атрибут уже установлен:

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

Если вы хотите использовать его программно:

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);
Барт Бург
источник
это действительно добавленные пробелы между символами? Бу ... если кто-то скопирует этот текст, он будет содержать лишние пробелы. No-Joy
johnw182
Требуется nullпроверка applyLetterSpacing, но кроме этого, спасатель жизни!
Барт ван Ниероп,
не работает, когда вы устанавливаете текст послесловия, а затем программно применяете интервалы
Джонатан
@jonney, должно быть, у меня так работает. Не могли бы вы прислать пример?
Барт Бург
1
Непрерывный пробел - «\ u00A0» - действительно полезен. Спасибо
Shayan_Aryan
11

после API> = 21 существует метод inbuild, предоставляемый TextView, который называется setLetterSpacing

проверьте это для получения дополнительной информации

Ravi
источник
3
Как можно так же в <21?
Рахул Деванавар 01
2
если (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 04
10

Я создал собственный класс, который расширяет TextViewи решает эту проблему ... Посмотрите мой ответ здесь =)

Педро Баррос
источник
\\ Большое спасибо за то, что сэкономили мое время ^ _ ^
Мухаммед Эль-Банна
0

Поскольку Android не поддерживает такую ​​вещь, вы можете сделать это вручную с помощью FontCreator. Есть хорошие возможности для изменения шрифта. Я использовал этот инструмент для создания собственного шрифта, даже если это займет некоторое время, но вы всегда можете использовать его в своих проектах.

Али
источник
-1

Для встраивания HTML-текста в текстовое представление вы можете использовать Html.fromHTML()синтаксис. Дополнительную информацию вы получите по адресу http://developer.android.com/reference/android/text/Html.html#fromHtml%28java.lang.String%29.

snehal_penurkar
источник
1
как это помогает? Я не знаю HTML-тега для межбуквенного интервала, который работает в TextView.
k2col