Как установить шрифт Spannable объекта с пользовательским шрифтом - PullRequest
59 голосов
/ 07 июля 2011

У меня есть объект Spannable, для которого я хочу установить его шрифт с помощью пользовательского шрифта, который я загружал ранее.

Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/font_Name.ttf");
Spannable span1 = /*Spannable Item*/;

/// I want to set span1 to have tf font face???
/// Here where I want help.

РЕДАКТИРОВАТЬ:
Моя проблема заключается в том, что я хочу установить два разных пользовательских шрифта длятекстовое представление, поэтому я работаю с Spannable

Ответы [ 6 ]

186 голосов
/ 24 мая 2012

Это поздний ответ, но он поможет другим решить проблему.

Используйте следующий код: (я использую шрифт Bangla and Tamil)

  TextView txt = (TextView) findViewById(R.id.custom_fonts);  
        txt.setTextSize(30);
        Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf");
        Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf");   
        SpannableStringBuilder SS = new SpannableStringBuilder("আমারநல்வரவு");
        SS.setSpan (new CustomTypefaceSpan("", font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        SS.setSpan (new CustomTypefaceSpan("", font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
        txt.setText(SS);

Результат:

enter image description here


CustomTypefaceSpan Класс:

package my.app;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

private final Typeface newType;

public CustomTypefaceSpan(String family, Typeface type) {
    super(family);
    newType = type;
}

@Override
public void updateDrawState(TextPaint ds) {
    applyCustomTypeFace(ds, newType);
}

@Override
public void updateMeasureState(TextPaint paint) {
    applyCustomTypeFace(paint, newType);
}

private static void applyCustomTypeFace(Paint paint, Typeface tf) {
    int oldStyle;
    Typeface old = paint.getTypeface();
    if (old == null) {
        oldStyle = 0;
    } else {
        oldStyle = old.getStyle();
    }

    int fake = oldStyle & ~tf.getStyle();
    if ((fake & Typeface.BOLD) != 0) {
        paint.setFakeBoldText(true);
    }

    if ((fake & Typeface.ITALIC) != 0) {
        paint.setTextSkewX(-0.25f);
    }

    paint.setTypeface(tf);
}
}

Ссылка

13 голосов
/ 22 сентября 2017

Создание класса CustomTypefaceSpan:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;

public class CustomTypefaceSpan extends MetricAffectingSpan {

    private final Typeface typeface;

    public CustomTypefaceSpan(Typeface typeface) {
        this.typeface = typeface;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, typeface);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, typeface);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        paint.setTypeface(tf);
    }
}

Использовать так же, как платформа Android охватывает классы:

    TextView textView = (TextView) findViewById(R.id.custom_fonts);
    Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf");
    Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf");
    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("আমারநல்வரவு");
    spannableStringBuilder.setSpan (new CustomTypefaceSpan(font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
    spannableStringBuilder.setSpan (new CustomTypefaceSpan(font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
    textView.setText(spannableStringBuilder);

Этот ответ основан на ответе Имрана Раны, но не распространяется на TypefaceSpan и затем отключает его функциональность. CustomTypefaceSpan расширяет MetricAffectingSpan напрямую.

Этот ответ разделяет дефект с ответом Имрана Раны. Промежуток не разделен. Т.е. если вы сделаете это (kotlin):

    val parcel = Parcel.obtain()
    TextUtils.writeToParcel(spannableStringBuilder, parcel, 0)
    parcel.setDataPosition(0)
    val sequence = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel)
    parcel.recycle()

Любые CustomTypefaceSpan объекты, установленные на spannableStringBuilder, не будут маршалироваться и не маршалироваться.

11 голосов
/ 17 июля 2018

Нам не нужно использовать CustomTypefaceSpan. Вот решение.

/**
* setCustomFontTypeSpan
* @param context
* @param source
* @param startIndex
* @param endIndex
* @param font
* @return
*/
public static SpannableString setCustomFontTypeSpan(Context context, String 
source, int startIndex, int endIndex, int font) {
      final SpannableString spannableString = new SpannableString(source);
      Typeface typeface = ResourcesCompat.getFont(context, font);
      spannableString.setSpan(new StyleSpan(typeface.getStyle()), 
      startIndex,endIndex,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}

String source = "Hello world";
SpannableString string = setCustomFontTypeSpan(context, source, 6, 
source.length(), R.font.open_sans_bold);
textView.setText(string);
10 голосов
/ 04 марта 2016

Если вы используете Roboto, вы можете установить другой TypefaceSpan в конструкторе

TypefaceSpan typefaceSpan = new TypefaceSpan("sans-serif-medium");

textView.setSpan(typefaceSpan, indexStart, textLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
1 голос
/ 07 июля 2011

Попробуйте сначала установить Spannable на TextView, а затем попробуйте назначить гарнитуру TextView с помощью myTextView.setTypeface(tf);

0 голосов
/ 28 апреля 2016

Вот пример, где str - ваша полная строка, а boldString - часть, которую нужно сделать жирным.

public static SpannableString getTextStyleSpan(String str, String boldString) {

        SpannableString formated = new SpannableString(str);

        int start1 = str.indexOf(boldString);
        int end1 = start1 + colorString1.length();

        formated.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start1, end1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        return formated;
    }
...