display smiley in textview and edittext in android - android

hello i am developing chat application in which i want to insert smiley
i have not much idea about it how to integrate and display in it
can u give me suggestion for doing the same ?
ImageGetter imageGetter = new ImageGetter() {
public Drawable getDrawable(String source) {
Drawable d = getResources().getDrawable(
R.drawable.happy);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
return d;
}
};
cs = Html.fromHtml(
"<img src='"
+ getResources()
.getDrawable(R.drawable.happy)
+ "'/>", imageGetter, null);
System.out.println("cs is:- " + cs);
edttxtemoji.setText(cs);
i found this code, in this it uses images, is this feasible ?
or there is another solutions ?
please give me better solution for this thanx in advance

Yes there is another way for showing smiley within the TextView or EditText. Build a Spannable text using ImageSpanand then setText the Spannable to TextView or EditText. Here is an post for the same.

To set Smiley in edittext
int value=R.id.ic_launcher;
Drawable Smiley = getResources().getDrawable(value);
Smiley.setBounds(0, 0, 15, 15);
SpannableStringBuilder builder = new SpannableStringBuilder();
String imgValue = "["+value+"]";
builder.append(imgValue);
builder.setSpan(new ImageSpan(Smiley), builder.length()-imgValue.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
edit_text.getText().insert(txt.getSelectionStart(), builder);
now to fetch smiley in listview or textview
textview.setText(addSmileySpans(context,edit_text.getText()));
public CharSequence addSmileySpans(Context context, CharSequence msg) {
SpannableStringBuilder builder = new SpannableStringBuilder(your_recieved_message);
Pattern pattern = Pattern.compile("\\[([^\\[\\]]+)\\]");
if( pattern != null )
{
Matcher matcher = pattern.matcher( your_recieved_message );
int matchesSoFar = 0;
while( matcher.find() )
{
CharSequence cs =matcher.group().subSequence(1, matcher.group().length()-1);
int value = Integer.parseInt(cs.toString());
System.out.println("pattern is::"+matcher.group().subSequence(1, matcher.group().length()-1));
int start = matcher.start() - (matchesSoFar * 2);
int end = matcher.end() - (matchesSoFar * 2);
Drawable Smiley = context.getResources().getDrawable(value);
Smiley.setBounds(0, 0,15,15);
builder.setSpan(new ImageSpan(Smiley), start + 1, end - 1, 0 );
builder.delete(start, start + 1);
builder.delete(end - 2, end -1);
matchesSoFar++;
}
}
return builder;
}

I think it is little bit late.
public void addSmily() {
CharSequence text = myEditText.getText();
int resource = R.drawable.ic_menu_emoticons ;
myEditText.setText(getSpannableText(text,resource));
}
private Spannable getSpannableText(CharSequence text, int smilyToAppend) {
Spannable spannable = Factory.getInstance().newSpannable(text+" ");
ImageSpan smilySpan = new ImageSpan(getApplicationContext(),smilyToAppend);
spannable.setSpan(smilySpan, spannable.length()-1, spannable.length(), 0);
return spannable;
}

Related

How to create overlapped image span?

I want to create a SpannableString with some emotions and text like this image.
Below is the method that I have used so for but it just attach emotions with text. Please suggest me how can I create such types of view.
private SpannableStringBuilder getLikeCountString(UserFeedData feedData, Context mContext) {
SpannableStringBuilder builder = new SpannableStringBuilder();
int emotionSize = (int) mContext.getResources().getDimension(R.dimen.emotion_size);
if (feedData.getEmotionTypes() != null) {
String[] emotions = feedData.getEmotionTypes().split(",");
for (String emotion : emotions) {
SpannableString emojSpan = new SpannableString(" ");
// Getting image based on emotion id
Drawable icon = ContextCompat.getDrawable(mContext, ContentDetailFragment.getLikeEmotionResource(Integer.valueOf(emotion.trim())));
//icon.setBounds(0, 0, (icon.getIntrinsicWidth() / 2) + 5, (icon.getIntrinsicHeight() / 2) + 5);
icon.setBounds(0, 0, emotionSize, emotionSize);
ImageSpan imageSpan = new ImageSpan(icon, ImageSpan.ALIGN_BOTTOM);
emojSpan.setSpan(imageSpan, 0, emojSpan.length() - 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
builder.append(emojSpan);
}
}
if (feedData.getContentLikes() > 0) {
builder.append(feedData.getContentLikes() + " ");
}
return builder;
}
Instead of using individual ImageSpans for each emoji, use one ImageSpan with LayerDrawable inside, one emoji per layer. You can do all kinds of overlaps with LayerDrawable.

How to change the colour of text programmatically [duplicate]

As the title says, I want to know is it possible to achieve two different colored characters in a single textview element.
yes, if you format the String with html's font-color property then pass it to the method Html.fromHtml(your text here)
String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));
You can prints lines with multiple colors without HTML as:
TextView textView = (TextView) findViewById(R.id.mytextview01);
Spannable word = new SpannableString("Your message");
word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(word);
Spannable wordTwo = new SpannableString("Your new message");
wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(wordTwo);
I have done this way:
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");
String surName = getColoredSpanned("Patel","#000080");
Set Text on TextView of two strings with different colors:
txtView.setText(Html.fromHtml(name+" "+surName));
Done
You can use Spannable to apply effects to your TextView:
Here is my example for colouring just the first part of a TextView text (while allowing you to set the color dynamically rather than hard coding it into a String as with the HTML example!)
mTextView.setText("Red text is here", BufferType.SPANNABLE);
Spannable span = (Spannable) mTextView.getText();
span.setSpan(new ForegroundColorSpan(0xFFFF0000), 0, "Red".length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
In this example you can replace 0xFFFF0000 with a getResources().getColor(R.color.red)
Use SpannableStringBuilder
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);
SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);
I have done this, try it:
TextView textView=(TextView)findViewById(R.id.yourTextView);//init
//here I am appending two string into my textView with two diff colors.
//I have done from fragment so I used here getActivity(),
//If you are trying it from Activity then pass className.this or this;
textView.append(TextViewUtils.getColoredString(getString(R.string.preString),ContextCompat.getColor(getActivity(),R.color.firstColor)));
textView.append(TextViewUtils.getColoredString(getString(R.string.postString),ContextCompat.getColor(getActivity(),R.color.secondColor)));
Inside your TextViewUtils class add this method:
/***
*
* #param mString this will setup to your textView
* #param colorId text will fill with this color.
* #return string with color, it will append to textView.
*/
public static Spannable getColoredString(String mString, int colorId) {
Spannable spannable = new SpannableString(mString);
spannable.setSpan(new ForegroundColorSpan(colorId), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.d(TAG,spannable.toString());
return spannable;
}
It's better to use the string in the strings file, as such:
<string name="some_text">
<![CDATA[
normal color <font color=\'#06a7eb\'>special color</font>]]>
</string>
Usage:
textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)
Kotlin version of #Swapnil Kotwal's answer.
Android Studio 4.0.1, Kotlin 1.3.72
val greenText = SpannableString("This is green,")
greenText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someGreenColor), null), 0, greenText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.text = greenText
val yellowText = SpannableString("this is yellow, ")
yellowText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someYellowColor), null), 0, yellowText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.append(yellowText)
val redText = SpannableString("and this is red.")
redText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someRedColor), null), 0, redText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.append(redText)
I don't know, since when this is possible, but you can simply add <font> </font> to your string.xml which will automatically change the color per text. No need to add any additional code such as spannable text etc.
Example
<string name="my_formatted_text">
<font color="#FF0707">THIS IS RED</font>
<font color="#0B132B">AND NOW BLUE</font>
</string>
I have write down some code for other question which is similar to this one, but that question got duplicated so i can't answer there so i am just putting my code here if someone looking for same requirement.
It's not fully working code, you need to make some minor changes to get it worked.
Here is the code:
I've used #Graeme idea of using spannable text.
String colorfulText = "colorfulText";
Spannable span = new SpannableString(colorfulText);
for ( int i = 0, len = colorfulText.length(); i < len; i++ ){
span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
((TextView)findViewById(R.id.txtSplashscreenCopywrite)).setText(span);
Random Color Method:
private int getRandomColor(){
Random rnd = new Random();
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
Using Kotlin and Extensions you can add colored text really easy and clean:
Create a file TextViewExtensions.kt with this content
fun TextView.append(string: String?, #ColorRes color: Int) {
if (string == null || string.isEmpty()) {
return
}
val spannable: Spannable = SpannableString(string)
spannable.setSpan(
ForegroundColorSpan(ContextCompat.getColor(context, color)),
0,
spannable.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
append(spannable)
}
Now is really easy to append text with color
textView.text = "" // Remove old text
textView.append("Red Text", R.color.colorAccent)
textView.append("White Text", android.R.color.white)
Basically is same as #Abdul Rizwan answer but using Kotlin, extensions, some validations and getting color inside extension.
Kotlin Answer
fun setTextColor(tv:TextView, startPosition:Int, endPosition:Int, color:Int){
val spannableStr = SpannableString(tv.text)
val underlineSpan = UnderlineSpan()
spannableStr.setSpan(
underlineSpan,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
val backgroundColorSpan = ForegroundColorSpan(this.resources.getColor(R.color.agreement_color))
spannableStr.setSpan(
backgroundColorSpan,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
val styleSpanItalic = StyleSpan(Typeface.BOLD)
spannableStr.setSpan(
styleSpanItalic,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
tv.text = spannableStr
}
After, call above function. You can call more than one:
setTextColor(textView, 0, 61, R.color.agreement_color)
setTextColor(textView, 65, 75, R.color.colorPrimary)
Output:
You can see underline and different colors with each other.
Try this:
mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" +
"<small>" + description + "</small>" + "<br />" +
"<small>" + DateAdded + "</small>"));
Use SpannableBuilder class instead of HTML formatting where it possible because it more faster then HTML format parsing.
See my own benchmark "SpannableBuilder vs HTML" on Github
Thanks!
If you want to give text color and text size in strings.xml then check out the below code:
<string name="txt_my_string">
<font fgcolor='#CFD8DC' > Text with given color </font> // Custom text color
<font size="14" > Text with given size </font> // Custom Text size
<font fgcolor='#3A55EA' size="14" > Text with given color and size </font> // Custom text color and size
</string>
Hope you understand easily :)
Awesome answers! I was able to use Spannable to build rainbow colored text (so this could be repeated for any array of colors). Here's my method, if it helps anyone:
private Spannable buildRainbowText(String pack_name) {
int[] colors = new int[]{Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE};
Spannable word = new SpannableString(pack_name);
for(int i = 0; i < word.length(); i++) {
word.setSpan(new ForegroundColorSpan(colors[i]), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return word;
}
And then I just setText(buildRainboxText(pack_name));
Note that all of the words I pass in are under 15 characters and this just repeats 5 colors 3 times - you'd want to adjust the colors/length of the array for your usage!
if (Build.VERSION.SDK_INT >= 24) {
Html.fromHtml(String, flag) // for 24 API and more
} else {
Html.fromHtml(String) // or for older API
}
for 24 API and more (flag)
public static final int FROM_HTML_MODE_COMPACT = 63;
public static final int FROM_HTML_MODE_LEGACY = 0;
public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;
More Info
Since API 24 you have FROM_HTML_OPTION_USE_CSS_COLORS so you can define colors in CSS instead of repeating it all time with font color="
Much clearer - when you have some html and you want to highlight some predefined tags - you just need to add CSS fragment at top of your html
Make common funtion for convert your string spannable like this.
//pass param textviewid ,start,end,string
//R.color.Red it's your color you can change it as requirement
fun SpannableStringWithColor(view: TextView,start:Int,end:Int, s: String) {
val wordtoSpan: Spannable =
SpannableString(s)
wordtoSpan.setSpan(
ForegroundColorSpan(ContextCompat.getColor(view.context, R.color.Red)),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
view.text = wordtoSpan
}
We can use anywhere as requirement like this.
SpannableStringWithColor(tvMobileNo,0,14,"Mobile Number : " + "123456789")
SpannableStringWithColor(tvEmail,0,5,"Email : " + "abc#gmail.com" "))
SpannableStringWithColor(tvAddress,0,8,"Address : " + "Delhi India")
Builder function in Kotlin:
val text = buildSpannedString {
append("My red text")
setSpan(
ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.red)),
3,
6,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
textView?.setText(text)
for kotlin:
#JvmStatic
#BindingAdapter(
"app:txt1",
"app:txt2",
"app:color1",
"app:color2",
requireAll = false
)
fun setColors(
txtView: AppCompatTextView,
txt1: String,
txt2: String,
color1: Int,
color2: Int
) {
txtView.setColors(txt1 = txt1, txt2 = txt2, color1 = color1, color2)
}
fun AppCompatTextView.setColors(txt1: String, txt2: String, color1: Int, color2: Int) {
val word: Spannable = SpannableString(txt1)
word.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this.context, color1)),
0,
word.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
this.text = word
val wordTwo: Spannable = SpannableString(txt2)
wordTwo.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this.context, color2)),
0,
wordTwo.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
this.append(wordTwo)
}
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:txt1="#{}"
app:txt2="#{}"
app:color1="#{}"
app:color2="#{}" />

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.

Single TextView with multiple colored text

As the title says, I want to know is it possible to achieve two different colored characters in a single textview element.
yes, if you format the String with html's font-color property then pass it to the method Html.fromHtml(your text here)
String text = "<font color=#cc0029>First Color</font> <font color=#ffcc00>Second Color</font>";
yourtextview.setText(Html.fromHtml(text));
You can prints lines with multiple colors without HTML as:
TextView textView = (TextView) findViewById(R.id.mytextview01);
Spannable word = new SpannableString("Your message");
word.setSpan(new ForegroundColorSpan(Color.BLUE), 0, word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(word);
Spannable wordTwo = new SpannableString("Your new message");
wordTwo.setSpan(new ForegroundColorSpan(Color.RED), 0, wordTwo.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.append(wordTwo);
I have done this way:
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");
String surName = getColoredSpanned("Patel","#000080");
Set Text on TextView of two strings with different colors:
txtView.setText(Html.fromHtml(name+" "+surName));
Done
You can use Spannable to apply effects to your TextView:
Here is my example for colouring just the first part of a TextView text (while allowing you to set the color dynamically rather than hard coding it into a String as with the HTML example!)
mTextView.setText("Red text is here", BufferType.SPANNABLE);
Spannable span = (Spannable) mTextView.getText();
span.setSpan(new ForegroundColorSpan(0xFFFF0000), 0, "Red".length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
In this example you can replace 0xFFFF0000 with a getResources().getColor(R.color.red)
Use SpannableStringBuilder
SpannableStringBuilder builder = new SpannableStringBuilder();
SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);
SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);
I have done this, try it:
TextView textView=(TextView)findViewById(R.id.yourTextView);//init
//here I am appending two string into my textView with two diff colors.
//I have done from fragment so I used here getActivity(),
//If you are trying it from Activity then pass className.this or this;
textView.append(TextViewUtils.getColoredString(getString(R.string.preString),ContextCompat.getColor(getActivity(),R.color.firstColor)));
textView.append(TextViewUtils.getColoredString(getString(R.string.postString),ContextCompat.getColor(getActivity(),R.color.secondColor)));
Inside your TextViewUtils class add this method:
/***
*
* #param mString this will setup to your textView
* #param colorId text will fill with this color.
* #return string with color, it will append to textView.
*/
public static Spannable getColoredString(String mString, int colorId) {
Spannable spannable = new SpannableString(mString);
spannable.setSpan(new ForegroundColorSpan(colorId), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.d(TAG,spannable.toString());
return spannable;
}
It's better to use the string in the strings file, as such:
<string name="some_text">
<![CDATA[
normal color <font color=\'#06a7eb\'>special color</font>]]>
</string>
Usage:
textView.text=HtmlCompat.fromHtml(getString(R.string.some_text), HtmlCompat.FROM_HTML_MODE_LEGACY)
Kotlin version of #Swapnil Kotwal's answer.
Android Studio 4.0.1, Kotlin 1.3.72
val greenText = SpannableString("This is green,")
greenText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someGreenColor), null), 0, greenText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.text = greenText
val yellowText = SpannableString("this is yellow, ")
yellowText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someYellowColor), null), 0, yellowText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.append(yellowText)
val redText = SpannableString("and this is red.")
redText.setSpan(ForegroundColorSpan(resources.getColor(R.color.someRedColor), null), 0, redText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
yourTextView.append(redText)
I don't know, since when this is possible, but you can simply add <font> </font> to your string.xml which will automatically change the color per text. No need to add any additional code such as spannable text etc.
Example
<string name="my_formatted_text">
<font color="#FF0707">THIS IS RED</font>
<font color="#0B132B">AND NOW BLUE</font>
</string>
I have write down some code for other question which is similar to this one, but that question got duplicated so i can't answer there so i am just putting my code here if someone looking for same requirement.
It's not fully working code, you need to make some minor changes to get it worked.
Here is the code:
I've used #Graeme idea of using spannable text.
String colorfulText = "colorfulText";
Spannable span = new SpannableString(colorfulText);
for ( int i = 0, len = colorfulText.length(); i < len; i++ ){
span.setSpan(new ForegroundColorSpan(getRandomColor()), i, i+1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
((TextView)findViewById(R.id.txtSplashscreenCopywrite)).setText(span);
Random Color Method:
private int getRandomColor(){
Random rnd = new Random();
return Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
}
Using Kotlin and Extensions you can add colored text really easy and clean:
Create a file TextViewExtensions.kt with this content
fun TextView.append(string: String?, #ColorRes color: Int) {
if (string == null || string.isEmpty()) {
return
}
val spannable: Spannable = SpannableString(string)
spannable.setSpan(
ForegroundColorSpan(ContextCompat.getColor(context, color)),
0,
spannable.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
append(spannable)
}
Now is really easy to append text with color
textView.text = "" // Remove old text
textView.append("Red Text", R.color.colorAccent)
textView.append("White Text", android.R.color.white)
Basically is same as #Abdul Rizwan answer but using Kotlin, extensions, some validations and getting color inside extension.
Kotlin Answer
fun setTextColor(tv:TextView, startPosition:Int, endPosition:Int, color:Int){
val spannableStr = SpannableString(tv.text)
val underlineSpan = UnderlineSpan()
spannableStr.setSpan(
underlineSpan,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
val backgroundColorSpan = ForegroundColorSpan(this.resources.getColor(R.color.agreement_color))
spannableStr.setSpan(
backgroundColorSpan,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
val styleSpanItalic = StyleSpan(Typeface.BOLD)
spannableStr.setSpan(
styleSpanItalic,
startPosition,
endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
tv.text = spannableStr
}
After, call above function. You can call more than one:
setTextColor(textView, 0, 61, R.color.agreement_color)
setTextColor(textView, 65, 75, R.color.colorPrimary)
Output:
You can see underline and different colors with each other.
Try this:
mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" +
"<small>" + description + "</small>" + "<br />" +
"<small>" + DateAdded + "</small>"));
Use SpannableBuilder class instead of HTML formatting where it possible because it more faster then HTML format parsing.
See my own benchmark "SpannableBuilder vs HTML" on Github
Thanks!
If you want to give text color and text size in strings.xml then check out the below code:
<string name="txt_my_string">
<font fgcolor='#CFD8DC' > Text with given color </font> // Custom text color
<font size="14" > Text with given size </font> // Custom Text size
<font fgcolor='#3A55EA' size="14" > Text with given color and size </font> // Custom text color and size
</string>
Hope you understand easily :)
Awesome answers! I was able to use Spannable to build rainbow colored text (so this could be repeated for any array of colors). Here's my method, if it helps anyone:
private Spannable buildRainbowText(String pack_name) {
int[] colors = new int[]{Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE, Color.RED, 0xFFFF9933, Color.YELLOW, Color.GREEN, Color.BLUE};
Spannable word = new SpannableString(pack_name);
for(int i = 0; i < word.length(); i++) {
word.setSpan(new ForegroundColorSpan(colors[i]), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return word;
}
And then I just setText(buildRainboxText(pack_name));
Note that all of the words I pass in are under 15 characters and this just repeats 5 colors 3 times - you'd want to adjust the colors/length of the array for your usage!
if (Build.VERSION.SDK_INT >= 24) {
Html.fromHtml(String, flag) // for 24 API and more
} else {
Html.fromHtml(String) // or for older API
}
for 24 API and more (flag)
public static final int FROM_HTML_MODE_COMPACT = 63;
public static final int FROM_HTML_MODE_LEGACY = 0;
public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4;
public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1;
public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0;
public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1;
More Info
Since API 24 you have FROM_HTML_OPTION_USE_CSS_COLORS so you can define colors in CSS instead of repeating it all time with font color="
Much clearer - when you have some html and you want to highlight some predefined tags - you just need to add CSS fragment at top of your html
Make common funtion for convert your string spannable like this.
//pass param textviewid ,start,end,string
//R.color.Red it's your color you can change it as requirement
fun SpannableStringWithColor(view: TextView,start:Int,end:Int, s: String) {
val wordtoSpan: Spannable =
SpannableString(s)
wordtoSpan.setSpan(
ForegroundColorSpan(ContextCompat.getColor(view.context, R.color.Red)),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
view.text = wordtoSpan
}
We can use anywhere as requirement like this.
SpannableStringWithColor(tvMobileNo,0,14,"Mobile Number : " + "123456789")
SpannableStringWithColor(tvEmail,0,5,"Email : " + "abc#gmail.com" "))
SpannableStringWithColor(tvAddress,0,8,"Address : " + "Delhi India")
Builder function in Kotlin:
val text = buildSpannedString {
append("My red text")
setSpan(
ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.red)),
3,
6,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
textView?.setText(text)
for kotlin:
#JvmStatic
#BindingAdapter(
"app:txt1",
"app:txt2",
"app:color1",
"app:color2",
requireAll = false
)
fun setColors(
txtView: AppCompatTextView,
txt1: String,
txt2: String,
color1: Int,
color2: Int
) {
txtView.setColors(txt1 = txt1, txt2 = txt2, color1 = color1, color2)
}
fun AppCompatTextView.setColors(txt1: String, txt2: String, color1: Int, color2: Int) {
val word: Spannable = SpannableString(txt1)
word.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this.context, color1)),
0,
word.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
this.text = word
val wordTwo: Spannable = SpannableString(txt2)
wordTwo.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this.context, color2)),
0,
wordTwo.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
this.append(wordTwo)
}
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:txt1="#{}"
app:txt2="#{}"
app:color1="#{}"
app:color2="#{}" />

SpannableString with Image example

I am looking for an example of how to build and display Android SpannableString with ImageSpan. Something like inline display of smileys.
Thanks a lot.
Found the following and it seems to do the job:
public class TestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textview);
SpannableString ss = new SpannableString("abc");
Drawable d = ContextCompat.getDrawable(this, R.drawable.icon32);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, 0, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
textView.setText(ss);
}
SpannableString + ImageSpan don't work in Android API 21 & 22 (I tested in Android Studio 1.2.1.1 in emulator), but if you do this:
TextView textView = (TextView) findViewById(R.id.textview);
textView.setTransformationMethod(null);
...
textView.setText(ss);
SpannableString + ImageSpan will work.
I was inspired by this post: https://stackoverflow.com/a/26959656/3706042
If anyone is still interested, I've created the a Java method to allow adding recursively a listed drawables to a text (set at the end to a textView) based on a "string to replace".
public void appendImages(#NonNull TextView textView,
#NonNull String text,
#NonNull String toReplace,
Drawable... drawables){
if(drawables != null && drawables.length > 0){
//list of matching positions, if any
List<Integer> positions = new ArrayList<>();
int index = text.indexOf(toReplace);
while (index >= 0) {
//add position
positions.add(index);
index = text.indexOf(toReplace, index + toReplace.length());
}
if(positions.size() > 0 && drawables.length >= positions.size()){
textView.setTransformationMethod(null);
SpannableString ss = new SpannableString(text);
int drawablesIndex = 0;
for(int position : positions){
Drawable drawable = drawables[drawablesIndex++];
//mandatory for Drawables
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ss.setSpan(new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE), position, position+toReplace.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
textView.setText(ss);
}
else Timber.w("The amount of matches to replace is %s and the number of drawables to apply is %s", positions.size(), drawables.length);
}
else Timber.w("The drawables array is null or empty.");
}
Usage:
appendImages(myTextView, "This is a ^ simple ^ test", "^", drawable1, drawable2);

Categories

Resources