How to get SpannableStringBuilder to add a range that is in a formatted string?

Background

Suppose I use SpannableStringBuilder to add a few things to it, and one of them is a line that I format from a strings.xml file that has an interval inside:

SpannableStringBuilder stringBuilder = new SpannableStringBuilder (); stringBuilder.append(...)... final SpannableString span = new SpannableString(...); span.setSpan(new BackgroundColorSpan(0xff990000), ...,...,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); stringBuilder.append(getString(R.string.string_to_format, span)); stringBuilder.append(...)... textView.setText(stringBuilder); 

Problem

Unfortunately, formatting such a line removes the span itself, so in my case there will be no text with background color.

This happens on the line "getString".

What i tried

If I just add span only (without "getString"), it works fine.

I also tried exploring Html.fromHtml, but it does not seem to support the background color for the text.

Question

Is it possible to format a string with a range, but still have a spacing inside?

In particular, the input is line A from the strings.xml file, in which there is only a placeholder (no special HTML tags) and another line B, which should replace the placeholder at run time. Line B should be highlighted for partial text.

In my case, the highlighted text is something to look for in line B.

+1
android textview spannablestring spannablestringbuilder
Jul 04 '16 at 23:25
source share
2 answers

Well, I found the answer to my special end, but I still would like to know if there are any better ways.

Here is what I did:

 String stringToSearchAt=... String query=... int queryIdx = stringToSearchAt.toLowerCase().indexOf(query); stringToSearchAt= stringToSearchAt.substring(0, queryIdx + query.length()) + "<bc/>" + stringToSearchAt.substring(queryIdx + query.length()); final String formattedStr=getString(..., stringToSearchAt); stringBuilder.append(Html.fromHtml(formattedStr, null, new TagHandler() { int start; @Override public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) { switch (tag) { case "bc": if (!opening) start = output.length() - query.length(); break; case "html": if (!opening) output.setSpan(new BackgroundColorSpan(0xff00bbaa), start, start + query.length(), 0); } } })); 

This is only useful for my case, but in the case of general formatting this will not be enough.

+2
Jul 09 '16 at 19:31
source share

formatting a stretched string may not be possible because it still uses String.format () to format String finilly, this is the Java API, and Span is the Android API.

But I think you can use the html string instead. Take a look at this HTML Markup Style document.

eg:

 String str = "Hi <strong><font color=\"#00bbaa\">%s</font></strong>, Welcome to <em><font color=\"#FF4081\">%s</font></em>"; String text = String.format(str, "Lucy", "Android"); Spanned spanned = Html.fromHtml(text); // after Html.fromHtml(), you can still change the Span SpannableString spannableString = new SpannableString(spanned); spannableString.setSpan(new BackgroundColorSpan(0xff990000), 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableString); 

result

enter image description here

if you want to put the string in the string.xml file, you may need to change '<' to '<', '% s' to '% 1 $ s'.

 <string name="from_offical">Hello &lt;strong>&lt;font color="#00bbaa">%1$s&lt;/font>&lt;/strong>, Welcome to &lt;em>&lt;font color="#00bbaa">%2$s&lt;/font>&lt;/em></string> 
+1
Jul 09 '16 at 7:29
source share



All Articles