How to have a SpannableStringBuilder append a span that's inside a formatted string?

雨燕双飞 提交于 2019-12-05 07:31:04

问题


Background

Suppose I use SpannableStringBuilder to append multiple stuff into it, and one of them is string that I format from the strings.xml file, which has a span 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);

The problem

Sadly, formatting such a string removes the span itself, so in my case, there won't be any text with a background color.

This happens on the line of the "getString".

What I've tried

If I just append the span alone (without "getString"), it works fine.

I also tried to investigate Html.fromHtml, but it doesn't seem to support a background color for text anyway.

The question

Is it possible to format a string that has a span, yet still have the span within?

More specifically, the input is a string A from the strings.xml file, which only has a placeholder (no special HTML tags), and another string B that is supposed to replace the placeholder at runtime. The string B should have a highlight for a partial text of itself.

In my case, the highlighted text is a something to search for within string B.


回答1:


OK, I've found an answer to my special end case, but I'd still like to know if there are better ways.

Here's 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 good for my case, but in the case of general formatting, this won't suffice.




回答2:


format a spanned string may be impossible, because it still use String.format() to format a String finilly, it's a Java API, and Span is Android API.

But I think you can use html string instead. Look at this document Styling with HTML markup.

for example:

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);

the result

if you want to put the string in the string.xml, 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>


来源:https://stackoverflow.com/questions/38193309/how-to-have-a-spannablestringbuilder-append-a-span-thats-inside-a-formatted-str

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!