Skip to content

Instantly share code, notes, and snippets.

@zerobranch
Created October 4, 2018 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zerobranch/e7e39810f71d8d58f2bdb90ea372ac72 to your computer and use it in GitHub Desktop.
Save zerobranch/e7e39810f71d8d58f2bdb90ea372ac72 to your computer and use it in GitHub Desktop.
SpannableUtils allows you to format a different part of a text
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;
final Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
final 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);
}
}
import android.content.Context;
import android.graphics.Typeface;
import android.support.annotation.ColorRes;
import android.support.annotation.FontRes;
import android.support.annotation.StringRes;
import android.support.v4.content.res.ResourcesCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.TypefaceSpan;
import android.view.View;
public class SpannableUtils {
private final Context context;
private final int messageRes;
private final String partText;
private int generalFontRes;
private int partFontRes;
private int generalColor;
private int partColor;
private int generalTextSize;
private int partTextSize;
private int includeLeft;
private int skipRight;
private View.OnClickListener partClickListener;
public SpannableUtils(Context context, @StringRes int messageRes, String partText) {
this.context = context;
this.messageRes = messageRes;
this.partText = partText;
}
public SpannableUtils generalFont(@FontRes int generalFontRes) {
this.generalFontRes = generalFontRes;
return this;
}
public SpannableUtils partFont(@FontRes int partFontRes) {
this.partFontRes = partFontRes;
return this;
}
public SpannableUtils generalColor(@ColorRes int generalColor) {
this.generalColor = generalColor;
return this;
}
public SpannableUtils partColor(@ColorRes int partColor) {
this.partColor = partColor;
return this;
}
public SpannableUtils partClickListener(View.OnClickListener partClickListener) {
this.partClickListener = partClickListener;
return this;
}
public SpannableUtils generalTextSize(int generalTextSize) {
this.generalTextSize = generalTextSize;
return this;
}
public SpannableUtils partTextSize(int partTextSize) {
this.partTextSize = partTextSize;
return this;
}
public SpannableUtils includeLeft(int includeLeft) {
this.includeLeft = includeLeft;
return this;
}
public SpannableUtils skipRight(int skipRight) {
this.skipRight = skipRight;
return this;
}
public Spannable build() {
final String message = context.getString(messageRes, partText);
final int startPartText = message.length() - partText.length() - includeLeft;
final int endPartText = message.length() - skipRight;
final Spannable contentSpannable = new SpannableString(message);
if (partClickListener != null) {
final ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
partClickListener.onClick(textView);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
contentSpannable.setSpan(clickableSpan, startPartText, endPartText, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (generalFontRes != 0 && partFontRes != 0) {
final Typeface generalFont = ResourcesCompat.getFont(context, generalFontRes);
final Typeface partFont = ResourcesCompat.getFont(context, partFontRes);
final TypefaceSpan generalFontSpan = new CustomTypefaceSpan("", generalFont);
final TypefaceSpan partFontSpan = new CustomTypefaceSpan("", partFont);
contentSpannable.setSpan(generalFontSpan, 0, startPartText - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
contentSpannable.setSpan(partFontSpan, startPartText, endPartText, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
} else if (generalFontRes != 0) {
final Typeface generalFont = ResourcesCompat.getFont(context, generalFontRes);
final TypefaceSpan generalFontSpan = new CustomTypefaceSpan("", generalFont);
contentSpannable.setSpan(generalFontSpan, 0, startPartText - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
if (generalColor != 0) {
contentSpannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(generalColor)),
0, startPartText - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
contentSpannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(partColor)),
startPartText, endPartText, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
if (generalTextSize != 0) {
contentSpannable.setSpan(new AbsoluteSizeSpan(generalTextSize, true),
0, startPartText - 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
contentSpannable.setSpan(new AbsoluteSizeSpan(partTextSize, true),
startPartText, endPartText, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
return contentSpannable;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment