How set Spannable object font with custom font How set Spannable object font with custom font android android

How set Spannable object font with custom font


This is a late answer but will help others to solve the issue.

Use the following code:(I'm using Bangla and Tamil font)

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

The outcome is:

enter image description here


CustomTypefaceSpan Class:

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;}@Overridepublic void updateDrawState(TextPaint ds) {    applyCustomTypeFace(ds, newType);}@Overridepublic 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);}}

Reference


Create a CustomTypefaceSpan class:

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

Use in the same way as the Android framework spans classes:

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

This answer is based on Imran Rana's answer but does not extend TypefaceSpan and then disable its functionality. CustomTypefaceSpan extends MetricAffectingSpan directly.

This answer shares a defect with Imran Rana's answer. The span is not parcelled. I.e if you do this (kotlin):

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

Any CustomTypefaceSpan objects set on spannableStringBuilder will not be marshalled and unmarshalled.


We don't need to use CustomTypefaceSpan. Here is the solution using StyleSpan.

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