Set different font and color to part of a TextView

16,228

Solution 1

You have to use a TypefaceSpan instead of a Typeface.

But since you are using a custom typeface you need to extend TypefaceSpan.

Check out this answer and create CustomTypefaceSpan class.

Now do the following:

Typeface robotoRegular = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Regular.ttf");
Typeface robotoBold = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Bold.ttf");

TypefaceSpan robotoRegularSpan = new CustomTypefaceSpan("", robotoRegular);
TypefaceSpan robotoBoldSpan = new CustomTypefaceSpan("", robotoBold);

// normal font for 1st 9 chars
sb.setSpan(robotoRegularSpan, 0, 9, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// bold font for rest of the chars
sb.setSpan(robotoBoldSpan, 9, s.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// also change color for rest of the chars
sb.setSpan(new ForegroundColorSpan(Color.BLUE), 9, s.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);

Solution 2

For peaple who prefer to make utils classes for this:

public static SpannableStringBuilder makeTextBold (Activity activity, String string, int fromCharIndex, int toCharIndex) {
    return makeTextBold(activity, new SpannableStringBuilder(string), fromCharIndex, toCharIndex);
}

public static SpannableStringBuilder makeTextBold (Activity activity, SpannableStringBuilder string, int fromCharIndex, int toCharIndex) {
    SpannableStringBuilder sb = new SpannableStringBuilder(string);
    Typeface bold = Typeface.createFromAsset(activity.getAssets(), "fonts/NexaBold.ttf");
    TypefaceSpan robotoBoldSpan = new CustomTypefaceSpan("", bold);
    sb.setSpan(robotoBoldSpan, fromCharIndex, toCharIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    return sb;
}

public static SpannableStringBuilder colorText (int resourceId, String string, Activity activity, int fromCharIndex, int toCharIndex) {
    return colorText(resourceId, new SpannableStringBuilder(string), activity, fromCharIndex, toCharIndex);
}

public static SpannableStringBuilder colorText (int resourceId, SpannableStringBuilder sb, Activity activity, int fromCharIndex, int toCharIndex) {
    sb.setSpan(new ForegroundColorSpan(activity.getResources().getColor(resourceId)), fromCharIndex, toCharIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    return sb;
}
Share:
16,228
Archie.bpgc
Author by

Archie.bpgc

Updated on June 05, 2022

Comments

  • Archie.bpgc
    Archie.bpgc about 2 years

    I tried this:

    String s = "Some big string"
    SpannableStringBuilder sb = new SpannableStringBuilder(s);
    //normal font for 1st 9 chars
    sb.setSpan(robotoRegular, 0,9,Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    //bold font for rest of the chars
    sb.setSpan(robotoBold, 9,s.length(),Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    //also change color for rest of the chars
    sb.setSpan(new ForegroundColorSpan(Color.BLACK), 9,s.length(),Spannable.SPAN_INCLUSIVE_INCLUSIVE);
    textView.setText(sb);
    

    But this didn't work.

    It only takes the latest setSpan, ie.., the Text color is being changed but not the font.

  • Zain
    Zain over 3 years
    I am looking for marking portions of a String using annotation programmatically .. appreciate if you can help in this
  • android developer
    android developer over 3 years
    @Zain If you do this programmatically , you don't need annotation. You just set the span according to the positions you need.
  • Zain
    Zain over 3 years
    thanks for instant feedback.. I need to do something customized that I have to use custom ReplacementSpan in it .. the problem is that it doesn't support multi-lined text unless using annotations
  • android developer
    android developer over 3 years
    @Zain Sorry but I didn't use it much. If you wish, I've made a sample of highlighting text within some string, programmatically, here: stackoverflow.com/a/57534078/878126 .
  • Rubén Viguera
    Rubén Viguera about 2 years
    I have edited your answer to fill the gaps on your original one