Showing colored text in textfield - android

i am writing text to a EditText .Can in show text in multiple colors as the
android:textColor
shall change the color of the entire text.
kindly update

You are welcome to apply ForegroundColorSpan and/or BackgroundColorSpan to portions of your text.
This sample project happens to apply BackgroundColorSpan (to highlight search results in a TextView), but the same principle holds for ForegroundColorSpan and an EditText widget.
private void searchFor(String text) {
TextView prose=(TextView)findViewById(R.id.prose);
Spannable raw=new SpannableString(prose.getText());
BackgroundColorSpan[] spans=raw.getSpans(0,
raw.length(),
BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index=TextUtils.indexOf(raw, text);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
+ text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index=TextUtils.indexOf(raw, text, index + text.length());
}
prose.setText(raw);
}

Related

set background for only a part of TextView

For example, I have a textview (multi line): aaaaaaaaabbbbaaa. I want to set background for only 'bbb' characters. I try to use Spannable but it doesn't work with my background is a image from drawable.
Many thanks.
using BackgroundColorSpan you can do that ,but Chinese doesn`t work in right way .
private void replaceText(TextView text, String str, int color) {
Spannable raw = new SpannableString(text.getText());
BackgroundColorSpan[] spans = raw.getSpans(0,raw.length(),BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index = TextUtils.indexOf(raw, str);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(color), index, index + str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index = TextUtils.indexOf(raw, str, index + str.length());
}
text.setText(raw);
}
private fun highlightTextPart(
textView: TextView,
mainString: String,
subString: String
) {
if (mainString.contains(subString)) {
val startIndex = mainString.indexOf(subString)
val endIndex = startIndex + subString.length
val spannableString = SpannableString(mainString)
spannableString.setSpan(
BackgroundColorSpan(Color.parseColor("#ff00ff")),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannableString
}
}
using
highlightTextPart("text text sell text", textView, "sell");

Android XML: L shape text view

I have 2 TextViews:
txtView1: User first name.
txtView2: User comment.
The design should be as shown in the picture below:
The problem is that i can't find a way to implement this design without adding a third TextView.
With 2 TextViews I got either overlapped text views or side by side text views.
Any ideas?
You can use even 1 TextView by using spans.
Here is what I got (I have only 1 text view):
And here is the code:
String firstName = "Pavel";
firstName = firstName.toUpperCase();
String firstPart = firstName + ": ";
String finalText = firstPart + "Text text text text text text text text text text text text text text text text text text text text text text text text text";
//0 - first line margin, 50 - other lines margin. Should be taken from resources.
LeadingMarginSpan paragraphSpan = new LeadingMarginSpan.Standard(0, 50);
//Bold span for the first name
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
//Color span for the notes text. Should be taken from resources
ForegroundColorSpan colorSpan = new ForegroundColorSpan(0x77000000);
Spannable spannableString = new SpannableString(finalText);
spannableString.setSpan(paragraphSpan, 0, finalText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(boldSpan, 0, firstPart.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
spannableString.setSpan(colorSpan, firstPart.length(), finalText.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
Really recommend to get yourself familiar with this article to better understand spans

Smily above the text in spannable string

I used the below code to add image span.
Drawable happySmiley = ctx.getResources().getDrawable(
R.drawable.img_smile);
happySmiley.setBounds(0, 0, happySmiley.getIntrinsicWidth(),
happySmiley.getIntrinsicHeight());
Drawable sadSmiley = ctx.getResources()
.getDrawable(R.drawable.ic_launcher);
sadSmiley
.setBounds(0, 0, sadSmiley.getIntrinsicWidth(),
sadSmiley.getIntrinsicHeight());
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append("Some text ");
builder.setSpan(new ImageSpan(happySmiley), builder.length()-1, builder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.append(". More text [sad_smiley_anchor]");
builder.setSpan(new ImageSpan(sadSmiley), builder.length()
- "[sad_smiley_anchor]".length(), builder.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvSS.setText(builder);
o/p Some text (smiley). More text (smiley).
But I want to display the smiley above the "Some" in "Some text". Like
(Smiley) (Smiley)
Some Text. More text.
If smiley can be set as background to "Some" in "Some text" like setForegroundSpan() etc. then also problem can be short out. Please comment on this.
Thanks

How to clear formatting from an EditText?

I have an EditText, and can add formatting such as bold, italic....but how can I remove it? I've looked into getSpans, filters, and other non-string things and haven't been able to make sense of them! Ideally, I'd like to be able to clear specific tags and all tags set around the selected text.
Update with my solution:
private String getSelectedText(){
int start = Math.max(mText.getSelectionStart(), 0);
int end = Math.max(mText.getSelectionEnd(), 0);
return mText.getText().toString().substring(Math.min(start, end), Math.max(start, end));
}
private void clearFormat(){
int s1 = Math.max(mText.getSelectionStart(), 0);
int s2 = Math.max(mText.getSelectionEnd(), 0);
String text = getSelectedText(); if(text==""){ return; }
EditText prose = mText;
Spannable raw = new SpannableString(prose.getText());
CharacterStyle[] spans = raw.getSpans(s1, s2, CharacterStyle.class);
for (CharacterStyle span : spans) {
raw.removeSpan(span);
}
prose.setText(raw);
//Re-select
mText.setSelection(Math.min(s1,s2), Math.max(s1, s2));
}
but how can I remove it?
Call removeSpan() on the Spannable.
For example, this method from this sample project searches for a search string in the contents of a TextView and assigns it a background color, but only after removing any previous background colors:
private void searchFor(String text) {
TextView prose=(TextView)findViewById(R.id.prose);
Spannable raw=new SpannableString(prose.getText());
BackgroundColorSpan[] spans=raw.getSpans(0,
raw.length(),
BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index=TextUtils.indexOf(raw, text);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
+ text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index=TextUtils.indexOf(raw, text, index + text.length());
}
prose.setText(raw);
}
}
what you could try is:
1- Create a custom style where your EditText will have "such as bold, italic..."
2- Be aware of using R.style.normalText to change it back to it's normal style at runtime
3- Change this styles depending on the behaviour you want to achieve via setTextAppearance(Context context, int resid)
Here is an example i found googling How to change a TextView's style at runtime
Edit: as your question is "How to clear formatting from an EditText" here is the specific answer as code:
editTextToClearStyle.setTextAppearance(this,R.style.normalText);
Please see the comment of the snippet below.
if (makeItalic) {
SpannableString spanString = new SpannableString(textViewDescription.getText());
spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, spanString.length(), 0);
this.textViewDescription.setText(spanString);
} else {
SpannableString spanString = new SpannableString(
textViewDescription.getText().toString()); // NOTE: call 'toString()' here!
spanString.setSpan(new StyleSpan(Typeface.NORMAL), 0, spanString.length(), 0);
this.textViewDescription.setText(spanString);
}
... just get the raw string characters by calling the toString() method.

Set color of TextView span in Android

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

Categories

Resources