I have a block of text coming from a webservice, and depending on some tags which I have predefined, I want to style the text before setting it to my TextView. For bold, italics, and underline, I was able to do this easily with the replaceAll command:
PageText = PageText.replaceAll("\\*([a-zA-Z0-9]+)\\*", "<b>$1</b>");
PageText = PageText.replaceAll("=([a-zA-Z0-9]+)=", "<i>$1</i>");
PageText = PageText.replaceAll("_([a-zA-Z0-9]+)_", "<u>$1</u>");
txtPage.setText(Html.fromHtml(PageText), TextView.BufferType.SPANNABLE);
So, to bold a word, surround it with *'s, for italics, surround with _.
But, for strikethrough, Html.fromHtml does not support the "strike" tag, so it can't be done this same way. I've seen examples of using Spannable to set the styling on one section of text, but it requires positional numbers. So, I guess I could loop through the text, searching for - (the tag to represent the strike), then searching for the next one, spanning the text in between, and repeating for all such strings. It will end up being 10 lines of looping code as opposed to 1 for the others, so I'm wondering if there is a more elegant solution out there.
If it is just TextView you can strike through using paint flags
TextView tv=(TextView) v.findViewById(android.R.id.text1);
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
#Suresh solution works if you want to strikethrough the entire TextView but if you want to strikethrough only some portions of the text then use the code below.
tvMRP.setText(text, TextView.BufferType.SPANNABLE);
Spannable spannable = (Spannable) tvMRP.getText();
spannable.setSpan(new StrikethroughSpan(), 3, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Here text is the text which we want out TextView to display, 3 is the no. of characters (starting from 0) from where the strikethrough will start.
You can do it with a custom TagHandler such as the one on this SO question:
Spanned parsed = Html.fromHtml(PageText, null, new MyHtmlTagHandler());
And the TagHandler implements the methods:
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
if(tag.equalsIgnoreCase("strike") || tag.equals("s")) {
processStrike(opening, output);
}
}
....
Are you sure Html.fromHtml doesn't support <strike>? It's listed in this Commonsware blog post
It looks like is not really supported, at least it does not work on Android 3.1.
#RMS2 if text is small you can split it into two or three separate text views and apply flag only to the one which you want, not perfect for long texts ;(
Most of the applications we work in are going to use text somewhere throughout the project and thankfully, KTX provides some extension functions when it comes to these parts. For text, we essentially have some functions available for the SpannableStringBuilder class.
For example, after instantiating a Builder instance we can use the build methods to append some bold text:
textView.text =buildSpannedString {
strikeThrough {
append(
value ?: ""
)
}
}
Related
I'm trying to show some statements to users from Firebase. There are titles and contents in these statements. Trying to write titles with a boldly styled post. However, I cannot change the code from the android studio because I've assigned the whole description child to a single TextView. instead, I used expressions such as "\ n", which is also used in string expressions. Is it possible to write bold headlines? if so how?
For example ; here is my
Can I write "ilk olarak bulunduğunuz federal devletteki bir..." here by a bold style?
yes you can display, the approach i use is setting html from firebase
<p><b>This text is bold</b></p>
and in android side
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tvDesc.setText(Html.fromHtml(strfromfirebase, Html.FROM_HTML_MODE_COMPACT));
} else {
tvDesc.setText(Html.fromHtml(strfromfirebase));
}
You need to use a SpannableString in this case.
For example if I want to bold the word "Hello" in "Hello World", I would do something like:
String word = "Hello World";
SpannableString spannableString = new SpannableString(word);
spannableString.setSpan(new StyleSpan(Typeface.BOLD),0,5,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
0 is the starting index and 5 is the ending index
I have a string array which contains couple of paragraphs .one word contains a italic font. How can i apply italic font for a particular word-textview . I know we can apply italic using spannable. but any other way?
<string-array name="string_collections" formatted="false">
<item>nutrients and weakens the <![CDATA[<i>Agni</i>]]>(digestive fire) within the stomach. Ayurveda recommends sipping minimal amounts during meals, with larger volumes spaced throughout the day, always away from food.
\n</item>
It is showing as text. no effect using Html.fromHtml method.
Try this one :-
Try Html.fromHtml(), and mark up your text with bold and italic HTML tags e.g:
Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff");
textView.setText(text);
I found a better approch my self.just use Matcher and get index of it.
java.util.regex.Pattern p =
java.util.regex.Pattern.compile("(^|\\s)word\\b",
java.util.regex.Pattern.CASE_INSENSITIVE);
final Matcher matcher = p.matcher(whole_text);
final SpannableStringBuilder spannable = new SpannableStringBuilder(whole_text);
while (matcher.find()) {
Log.e("Spannable", "Spannable" +"Matchfound");
//apply span which you want.
spannable.setSpan(new StyleSpan(Typeface.ITALIC), matcher.start(), matcher.end(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tvtextmsg.setText(spannable);
Note:just found some another issue i have faced while using
if you are trying to do as below
tvtextmsg.setText(spannable+"\n \n"+another_text);
spannable will not be effected .you need do as
tvtextmsg.setText(spannable);
tvtextmsg.append("\n \n"+another_text)
I am trying to get a textview to process a hyperlink as well as phone numbers. Say my text is:
"555-555-555, www.google.com, Google!"
If I run Html.fromHtml() on this string, then the TextView shows Google! correctly as a clickable link but not the other two.
If I run Linkify.addLinks(TextView, Linkify.All) on the TextView, then the first two are correctly recognized as a phone number and url, but the html is not processed in the last one.
If I run both of them, then either one or the other is honored, but not both at the same time. (Html.fromHtml will remove the html tags there, but it won't be a link if linkify is called after)
Any ideas on how to get both of these functions to work simultaneously? So all the links are processed correctly? Thanks!
Edit: Also, the text is changed dynamically so I'm not sure how I would be able to go about setting up a Linkify pattern for that.
It's because Html.fromHtml and Linkify.addLinks removes previous spans before processing the text.
Use this code to get it work:
public static Spannable linkifyHtml(String html, int linkifyMask) {
Spanned text = Html.fromHtml(html);
URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);
SpannableString buffer = new SpannableString(text);
Linkify.addLinks(buffer, linkifyMask);
for (URLSpan span : currentSpans) {
int end = text.getSpanEnd(span);
int start = text.getSpanStart(span);
buffer.setSpan(span, start, end, 0);
}
return buffer;
}
try to set movement method on your textview instead of using Linkify:
textView.setMovementMethod(LinkMovementMethod.getInstance());
In your TextView's xml layout, you should add the following:
android:autoLink="all"
android:linksClickable="true"
Then you should remove your Linkify code in Java.
It works somehow, but I dont know why. I added a question to see if someone can explain the behavior: Using Linkify.addLinks combine with Html.fromHtml
There's TextView.append(), but that adds the text to the end of the TextView. I want what I append to go in the beginning (ie, show up on the top of the TextView box).
Have you tried this
textview.setText(" append string" + textView.getText());
Though the spannables will get lost by this method.
If you're concerned about spannables, you can use something like this:
textView.getEditableText().insert(0, "string to prepend");
The getEditableText() returned null to me. Instead, to prepend text to a spannable, I set the text buffertype to SPANNABLE:
in code:
myTextView.setText(myText, TextView.BufferType.SPANNABLE);
or using xml property android:bufferType on your TextView.
Then cast the getText() to Spannable, after which I concat the extra text with existing text:
Spannable currentText = (Spannable) tvTitle.getText();
CharSequence indexedText = TextUtils.concat(String.format("%d. ", index), currentText);
myTextView.setText(indexedText);
As far as I can tell all functions are available from API level 1.
Then use the string you want to append say "hello" to the textview as
textview.setText("hello"+textView.getText())
I'm struggling with using EditText and Spannable text object, These days, I've read API documents around ten times, even I'm not certain that I understand correctly. So I'm looking for a kind of example which show me how to utilize EditText and Spannable.
Since you don't specify what you can't grasp from the API it's hard to answer your questions (short answer: rewrite your question to a specific questions rather than a general one).
A typical Spannable-example is something like this to turn selected text in an EditText into Italic:
Spannable str = mBodyText.getText();
if(mBodyText.getSelectionEnd() > mBodyText.getSelectionStart())
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC),
mBodyText.getSelectionStart(), mBodyText.getSelectionEnd(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
else
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC),
mBodyText.getSelectionEnd(),
mBodyText.getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
This is cut and pasted from something else, so your direct-pastability might have suffered, but it at least shows a working example of a Spannable (in this case a StyleSpan). In the API you can find the other types of Spans (notably ImageSpan, which is a common questions among newly converted droiders).
I'm just starting to try to figure it out too, and it seems unnecessarily tricky.
Here's a working method to add NEW spannable text to an existing view. I wanted to add colored text to a view, and this seemed like the only way to do it.
Though it feels like an ugly hack, you can create a dummy TextView (not shown anywhere) and style the text there, then append that styled text to wherever you want. Credit for it goes to iifuzz at anddev.org. My code looks like so:
spanbuffer = new TextView(context);
spanbuffer.setText(newText, TextView.BufferType.SPANNABLE);
Spannable s = (Spannable) spanbuffer.getText();
s.setSpan(new ForegroundColorSpan(Color.RED), 0, newText.length() - 1, 0);
this.append(s);
I think you're supposed to be able to create new spannable text using the SpannableFactory, like so:
Spannable s = Spannable.Factory.getInstance().newSpannable(newText);
but I couldn't get this text to actually show new span effects, so I gave up.