Is it possible to set multiple colors for different pieces of text inside a TextView with if condition?
Here is my code:
mColoredText = findViewById(R.id.questionText);
String mColoredString = "BLACK RED GREEN YELLOW ORANGE BLUE WHITE";
SpannableStringBuilder builder = new SpannableStringBuilder();
if(mColoredString.contains("RED")) {
String red = "RED";
SpannableString redSpannable = new SpannableString(red);
redSpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, red.length(), 0);
builder.append(redSpannable);
}
if(mColoredString.contains("YELLOW")) {
String yellow = "YELLOW";
SpannableString whiteSpannable = new SpannableString(yellow);
whiteSpannable.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, yellow.length(), 0);
builder.append(whiteSpannable);
}
if(mColoredString.contains("BLUE")) {
String blue = "BLUE";
SpannableString blueSpannable = new SpannableString(blue);
blueSpannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, blue.length(), 0);
builder.append(blueSpannable);
}
mColoredText.setText(builder, TextView.BufferType.SPANNABLE);
But the end result is always print: RED YELLOW BLUE with it's color, just three text.
I expect BLACK RED GREEN YELLOW ORANGE BLUE WHITE written all together, and white color applicable if no spannable color.
Try this code..
textView = findViewById(R.id.tvData);
String mColoredString = "BLACK RED GREEN YELLOW ORANGE BLUE WHITE";
SpannableStringBuilder builder = new SpannableStringBuilder();
String strArray[] = mColoredString.split(" ");
for (int i = 0; i < strArray.length; i++) {
if (strArray[i].equals("RED")) {
SpannableString redSpannable = new SpannableString(strArray[i]);
redSpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, strArray[i].length(), 0);
builder.append(redSpannable);
} else if (strArray[i].equals("YELLOW")) {
SpannableString whiteSpannable = new SpannableString(strArray[i]);
whiteSpannable.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, strArray[i].length(), 0);
builder.append(whiteSpannable);
} else if (strArray[i].equals("BLUE")) {
SpannableString blueSpannable = new SpannableString(strArray[i]);
blueSpannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, strArray[i].length(), 0);
builder.append(blueSpannable);
} else {
builder.append(strArray[i]);
}
}
textView.setText(builder);
}
You create a new builder and add only RED YELLOW and BLUE colors to it. That is why you see always RED YELLOW BLUE.
If you want to update the original text then you have to make a SpannableString from it first.
SpannableString mColoredString = new SpannableString("BLACK RED GREEN YELLOW ORANGE BLUE WHITE");
if (mColoredString.toString().contains("RED")) {
mColoredString.setSpan(new ForegroundColorSpan(Color.RED), 6, 9, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (mColoredString.toString().contains("YELLOW")) {
mColoredString.setSpan(new ForegroundColorSpan(Color.YELLOW), 16, 22, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (mColoredString.toString().contains("BLUE")) {
mColoredString.setSpan(new ForegroundColorSpan(Color.BLUE), 30, 34, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
questionText.setText(mColoredString);
Please read this article for a detailed explanation.
EDIT:
If you don't know the start and end positions then you have to calculate them:
if (mColoredString.toString().contains("YELLOW")) {
int start = mColoredString.toString().indexOf("YELLOW");
int end = start + "YELLOW".length();
mColoredString.setSpan(new ForegroundColorSpan(Color.YELLOW), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
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.
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);
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;
}
check this code :-
protected void onDraw(Canvas canvas) {
Paint circlePaint = new Paint();
Typeface mType = Typeface.create(Typeface.SANS_SERIF, Typeface.ITALIC);
circlePaint.setTextSize(25);
circlePaint.setColor(Color.RED);
circlePaint.setTypeface(mType);
canvas.drawText("Default Typeface", 50, 100, circlePaint);
//
circlePaint.setFlags(Paint.UNDERLINE_TEXT_FLAG);
circlePaint.setColor(Color.YELLOW);
canvas.drawText("Underline Text Flag", 50, 120, circlePaint);
//
circlePaint.setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
circlePaint.setColor(Color.GREEN);
canvas.drawText("Strike Thru Text Flag", 50, 140, circlePaint);
//
circlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.WHITE);
canvas.drawText("Anti Alias Flag", 50, 160, circlePaint);
//
circlePaint.setFlags(Paint.DEV_KERN_TEXT_FLAG);
circlePaint.setColor(Color.WHITE);
canvas.drawText("Dev Kern Text Flag", 50, 180, circlePaint);
//
circlePaint.setFlags(Paint.FAKE_BOLD_TEXT_FLAG);
circlePaint.setColor(Color.CYAN);
canvas.drawText("Fake Bold Text Flag", 50, 200, circlePaint);
}
Google actually gave an official answer about this on this video:
Also you can follow the docs explaining it as well
Please be aware that this approach is just Android P+ compatible and strings cannot be formatted (using %1$s params)
strings.xml
<string name="test">Hello <annotation font="sans-serif-medium">World!</annotation></string>
And in code:
val spanned = context.getText(R.string.title) as SpannedString
val spannable = SpannableString(spanned)
spanned.getSpans(0, spanned.length, Annotation::class.java).filter { annotation ->
annotation.key == "font"
}.forEach { annotation ->
val typeface = Typeface.create(annotation.value, Typeface.NORMAL)
spannable.setSpan(TypefaceSpan(typeface),
spanned.getSpanStart(annotation),
spanned.getSpanEnd(annotation),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
textView.text = spannable
String aux = getInserzionista(offerta.getIdInserzionista());
sotto_titolo.setText("Offerta dal " + aux);
int inizio = 12;
int fine = 11+aux.length();
sotto_titolo.setMovementMethod(LinkMovementMethod.getInstance());
sotto_titolo.setText(sotto_titolo.getText().toString(),BufferType.SPANNABLE);
Spannable mySpannable = (Spannable) sotto_titolo.getText();
ClickableSpan myClickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
}
};
//if i put this, not work
mySpannable.setSpan(new ForegroundColorSpan(Color.RED), inizio, fine, 0);
mySpannable.setSpan(myClickableSpan, inizio, fine + 1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
But if i put this:
mySpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);
It works, because the text from 0 to 4 is colored!
So, my question is:
How can I change the color of the link (the one colored blue and underlined)?
Thanks
because you set a static value 4 in this line mySpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);. Set text length in place of 4.
Have you tried using updateDrawState()?
Is it possible to have a textview to have different color for every word? Or even every letter? I tried extending textview and creating it but however I thought of the problem is, how would I draw all the the text out at the same time with different colors?
Use android.text.Spannable
final SpannableStringBuilder str = new SpannableStringBuilder(text);
str.setSpan(
new ForegroundColorSpan(Color.BLUE),
wordStart,
wordEnd,
SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
);
myTextView.setText(str);
EDIT: To make all "Java" green
final Pattern p = Pattern.compile("Java");
final Matcher matcher = p.matcher(text);
final SpannableStringBuilder spannable = new SpannableStringBuilder(text);
final ForegroundColorSpan span = new ForegroundColorSpan(Color.GREEN);
while (matcher.find()) {
spannable.setSpan(
span, matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
myTextView.setText(spannable);
The SpannableString class allows you to easily format certain pieces (spans) of a string one way and other pieces another by applying extensions of CharacterStyle (i.e. ForegroundColorSpan) via the setSpan method.
You can try This:
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
richTextView = (TextView)findViewById(R.id.rich_text);
// this is the text we'll be operating on
SpannableString text = new SpannableString("Lorem ipsum dolor sit amet");
// make "Lorem" (characters 0 to 5) red
text.setSpan(new ForegroundColorSpan(Color.RED), 0, 5, 0);
// make "ipsum" (characters 6 to 11) one and a half time bigger than the textbox
text.setSpan(new RelativeSizeSpan(1.5f), 6, 11, 0);
// make "dolor" (characters 12 to 17) display a toast message when touched
final Context context = this;
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View view) {
Toast.makeText(context, "dolor", Toast.LENGTH_LONG).show();
}
};
text.setSpan(clickableSpan, 12, 17, 0);
// make "sit" (characters 18 to 21) struck through
text.setSpan(new StrikethroughSpan(), 18, 21, 0);
// make "amet" (characters 22 to 26) twice as big, green and a link to this site.
// it's important to set the color after the URLSpan or the standard
// link color will override it.
text.setSpan(new RelativeSizeSpan(2f), 22, 26, 0);
text.setSpan(new URLSpan("http://www.chrisumbel.com"), 22, 26, 0);
text.setSpan(new ForegroundColorSpan(Color.GREEN), 22, 26, 0);
// make our ClickableSpans and URLSpans work
richTextView.setMovementMethod(LinkMovementMethod.getInstance());
// shove our styled text into the TextView
richTextView.setText(text, BufferType.SPANNABLE);
}
The result will look like this:
For more detail see Chris Umbel blog.
Yes, you can do this with Spannable and SpannableStringBuilder. See Is there any example about Spanned and Spannable text for one example.
For the various ways to format text (background color, foreground color, clickable, etc.), see CharacterStyle.
Is it possible to set the color of just span of text in a TextView?
I would like to do something similar to the Twitter app, in which a part of the text is blue. See image below:
(source: twimg.com)
Another answer would be very similar, but wouldn't need to set the text of the TextView twice
TextView TV = (TextView)findViewById(R.id.mytextview01);
Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");
wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TV.setText(wordtoSpan);
Here is a little help function. Great for when you have multiple languages!
private void setColor(TextView view, String fulltext, String subtext, int color) {
view.setText(fulltext, TextView.BufferType.SPANNABLE);
Spannable str = (Spannable) view.getText();
int i = fulltext.indexOf(subtext);
str.setSpan(new ForegroundColorSpan(color), i, i + subtext.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
I always find visual examples helpful when trying to understand a new concept.
Background Color
SpannableString spannableString = new SpannableString("Hello World!");
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(backgroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
Foreground Color
SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
Combination
SpannableString spannableString = new SpannableString("Hello World!");
ForegroundColorSpan foregroundSpan = new ForegroundColorSpan(Color.RED);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.YELLOW);
spannableString.setSpan(foregroundSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(backgroundSpan, 3, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
Further Study
Explain the meaning of Span flags like SPAN_EXCLUSIVE_EXCLUSIVE
Android Spanned, SpannedString, Spannable, SpannableString and CharSequence
If you want more control, you might want to check the TextPaint class. Here is how to use it:
final ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(final View textView) {
//Your onClick code here
}
#Override
public void updateDrawState(final TextPaint textPaint) {
textPaint.setColor(yourContext.getResources().getColor(R.color.orange));
textPaint.setUnderlineText(true);
}
};
Set your TextView´s text spannable and define a ForegroundColorSpan for your text.
TextView textView = (TextView)findViewById(R.id.mytextview01);
Spannable wordtoSpan = new SpannableString("I know just how to whisper, And I know just how to cry,I know just where to find the answers");
wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(wordtoSpan);
Another way that could be used in some situations is to set the link color in the properties of the view that is taking the Spannable.
If your Spannable is going to be used in a TextView, for example, you can set the link color in the XML like this:
<TextView
android:id="#+id/myTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorLink="#color/your_color"
</TextView>
You can also set it in the code with:
TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setLinkTextColor(your_color);
Here's a Kotlin Extension Function I have for this
fun TextView.setColouredSpan(word: String, color: Int) {
val spannableString = SpannableString(text)
val start = text.indexOf(word)
val end = text.indexOf(word) + word.length
try {
spannableString.setSpan(ForegroundColorSpan(color), start, end,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
text = spannableString
} catch (e: IndexOutOfBoundsException) {
println("'$word' was not not found in TextView text")
}
}
Use it after you have set your text to the TextView like so
private val blueberry by lazy { getColor(R.color.blueberry) }
textViewTip.setColouredSpan("Warning", blueberry)
String text = "I don't like Hasina.";
textView.setText(spannableString(text, 8, 14));
private SpannableString spannableString(String text, int start, int end) {
SpannableString spannableString = new SpannableString(text);
ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);
spannableString.setSpan(highlightSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new BackgroundColorSpan(0xFFFCFF48), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new RelativeSizeSpan(1.5f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}
Output:
Set Color on Text by passing String and color:
private String getColoredSpanned(String text, String color) {
String input = "<font color=" + color + ">" + text + "</font>";
return input;
}
Set text on TextView / Button / EditText etc by calling below code:
TextView:
TextView txtView = (TextView)findViewById(R.id.txtView);
Get Colored String:
String name = getColoredSpanned("Hiren", "#800000");
Set Text on TextView:
txtView.setText(Html.fromHtml(name));
Done
There's a factory for creating the Spannable, and avoid the cast, like this:
Spannable span = Spannable.Factory.getInstance().newSpannable("text");
Just to add to the accepted answer, as all the answers seem to talk about android.graphics.Color only: what if the color I want is defined in res/values/colors.xml?
For example, consider Material Design colors defined in colors.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="md_blue_500">#2196F3</color>
</resources>
(android_material_design_colours.xml is your best friend)
Then use ContextCompat.getColor(getContext(), R.color.md_blue_500) where you would use Color.BLUE, so that:
wordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
becomes:
wordtoSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.md_blue_500)), 15, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Where I found that:
Working with spans in Android – Michael Spitsin – Medium
Using kotlin-ktx, you can achieve it easily
bindView?.oneTimePasswordTitle?.text = buildSpannedString {
append("One Time Password ")
inSpans(
ForegroundColorSpan(ContextCompat.getColor(bindView?.oneTimePasswordTitle?.context!!,R.color.colorPrimaryText))
){
append(" (As Registered Email)")
}
}
Some answers here aren't up to date. Because, you will (in most of cases) add a custom clic action on your link.
Besides, as provided by the documentation help, your spanned string link color will have a default one.
"The default link color is the theme's accent color or android:textColorLink if this attribute is defined in the theme".
Here is the way to do it safely.
private class CustomClickableSpan extends ClickableSpan {
private int color = -1;
public CustomClickableSpan(){
super();
if(getContext() != null) {
color = ContextCompat.getColor(getContext(), R.color.colorPrimaryDark);
}
}
#Override
public void updateDrawState(#NonNull TextPaint ds) {
ds.setColor(color != -1 ? color : ds.linkColor);
ds.setUnderlineText(true);
}
#Override
public void onClick(#NonNull View widget) {
}
}
Then to use it.
String text = "my text with action";
hideText= new SpannableString(text);
hideText.setSpan(new CustomClickableSpan(){
#Override
public void onClick(#NonNull View widget) {
// your action here !
}
}, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
yourtextview.setText(hideText);
// don't forget this ! or this will not work !
yourtextview.setMovementMethod(LinkMovementMethod.getInstance());
Hope this will strongly help !
create textview in ur layout
paste this code in ur MainActivity
TextView textview=(TextView)findViewById(R.id.textviewid);
Spannable spannable=new SpannableString("Hello my name is sunil");
spannable.setSpan(new ForegroundColorSpan(Color.BLUE), 0, 5,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textview.setText(spannable);
//Note:- the 0,5 is the size of colour which u want to give the strring
//0,5 means it give colour to starting from h and ending with space i.e.(hello), if you want to change size and colour u can easily
Below works perfectly for me
tvPrivacyPolicy = (TextView) findViewById(R.id.tvPrivacyPolicy);
String originalText = (String)tvPrivacyPolicy.getText();
int startPosition = 15;
int endPosition = 31;
SpannableString spannableStr = new SpannableString(originalText);
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableStr.setSpan(underlineSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
ForegroundColorSpan backgroundColorSpan = new ForegroundColorSpan(Color.BLUE);
spannableStr.setSpan(backgroundColorSpan, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
StyleSpan styleSpanItalic = new StyleSpan(Typeface.BOLD);
spannableStr.setSpan(styleSpanItalic, startPosition, endPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tvPrivacyPolicy.setText(spannableStr);
Output for above code
From the developer docs, to change the color and size of a spannable:
1- create a class:
class RelativeSizeColorSpan(size: Float,#ColorInt private val color: Int): RelativeSizeSpan(size) {
override fun updateDrawState(textPaint: TextPaint?) {
super.updateDrawState(textPaint)
textPaint?.color = color
}
}
2 Create your spannable using that class:
val spannable = SpannableStringBuilder(titleNames)
spannable.setSpan(
RelativeSizeColorSpan(1.5f, Color.CYAN), // Increase size by 50%
titleNames.length - microbe.name.length, // start
titleNames.length, // end
Spannable.SPAN_EXCLUSIVE_INCLUSIVE
)
You can use extension function in Kotlin
fun CharSequence.colorizeText(
textPartToColorize: CharSequence,
#ColorInt color: Int
): CharSequence = SpannableString(this).apply {
val startIndexOfText = this.indexOf(textPartToColorize.toString())
setSpan(ForegroundColorSpan(color), startIndexOfText, startIndexOfText.plus(textPartToColorize.length), 0)
}
Usage:
val colorizedText = "this text will be colorized"
val myTextToColorize = "some text, $colorizedText continue normal text".colorizeText(colorizedText,ContextCompat.getColor(context, R.color.someColor))
viewBinding.myTextView.text = myTextToColorize
Now you can use the CodeView library to highlight patterns with different colors easily, for example, to highlight all URLs inside the text with the blue color you just need to write
CodeView codeView = findViewById(R.id.codeview);
codeView.addSyntaxPattern(Patterns.WEB_URL, Color.BLUE);
codeView.setTextHighlighted(text);
CodeView Repository URL: https://github.com/amrdeveloper/codeview
I got the same issue.
#Dano's answer is absolutely correct. But it doesn't work for me.
After that, I found the issue I have added ClickableSpan. So it will change my color with another color (accent color)
Issue
SpannableStringBuilder will not change color and undline when you add a ClickableSpan after ForegroundColorSpan or UnderlineSpan.
Solution
1. With ClickableSpan
You can Override the updateDrawState method inside ClickableSpan.
In the updateDrawState method, you should remove the super callback.
After that, you should Modify your text paint as required.
2. Without ClickableSpan
Add ForegroundColorSpan to change the text color
Add UnderlineSpan to add underline in text.
First Part **Second Part should be Bold** last Part
This text should be changed using SpannableString
import android.graphics.Typeface.BOLD
import android.text.Spannable
import android.text.Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
import android.text.SpannableString
import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
val firstPart = "First Part "
val secondPart = "Second Part should be Bold"
val thirdPart = " last Part"
val finalString = firstPart + secondPart + thirdPart
val sb: Spannable = SpannableString(finalString).also {
// ... Change text Colour
it.setSpan(
ForegroundColorSpan(getColor(requireContext(), R.color.pink)),
finalString.indexOf(secondPart),
finalString.indexOf(secondPart) + secondPart.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
// ... Make the text Bold
it.setSpan(
StyleSpan(BOLD),
finalString.indexOf(secondPart),
finalString.indexOf(secondPart) + secondPart.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
// ... Change Background Colour
it.setSpan(
BackgroundColorSpan(getColor(requireContext(), R.color.lightPink)),
finalString.indexOf(secondPart) - 1,
finalString.indexOf(secondPart) + secondPart.length + 1,
SPAN_EXCLUSIVE_EXCLUSIVE
)
}
yourTextView.text = sb