如何使用 Spannable Builder 动态更改部分字符串颜色
How to dynamically change part of string's color with SpannableBuilder
我正在动态格式化字符串,如 Android 文档中的以下示例:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
然后我这样设置值:
var text = getString(R.string.welcome_messages, username, mailCount)
如何为 username 设置绿色,为 mailCount 设置红色?
我也需要它适用于多个语言环境。所以我不能自己硬编码位置。
之前我把这个字符串分成4个部分,然后可以很容易地使用SpannableBuilder
来改变颜色。
HTML 和 CDATA 不合适。我们需要为 Android 和 iOS.
保留相同的字符串
声明字符串
<string name="string_formatted"><![CDATA[ Hello, <font color=#145A14> %1$s!</font> You have %2$d new messages]]></string>
在Activity
TextView tv = findViewById(R.id.mytext);
tv.setText(Html.fromHtml(getString(R.string.html_formatted,"XYZ", 5)));
您可以根据需要使用 SpannableString
和 setSpan
。
<string name="welcome_message">Hello, %1$s! You have %2$d new messages.</string>
void setSpannableTextWithColor(TextView view, int resourceId, String username, int userColor, int messageCount, int countColor) {
String fulltext = getString(resourceId, username, messageCount);
view.setText(fulltext, TextView.BufferType.SPANNABLE);
Spannable str = (Spannable) view.getText();
int usernameIndex = fulltext.indexOf(username);
str.setSpan(new ForegroundColorSpan(userColor), usernameIndex, usernameIndex + username.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
int countIndex = fulltext.indexOf(String.valueOf(messageCount));
str.setSpan(new ForegroundColorSpan(countColor), countIndex, countIndex + String.valueOf(messageCount).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
setSpannableTextWithColor(findViewById(R.id.text_view1), R.string.welcome_message, "Viktor Vostrikov", Color.GREEN, 122, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view2), R.string.welcome_message, "Виктор Востриков", Color.GREEN, 2, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view3), R.string.welcome_message, "فيكتور فوستريكوف", Color.GREEN, 2000, Color.RED);
输出:
使用Jetpack core-ktx,可以简洁的写成:
val s = "Beautiful City".toSpannable()
s[0..9] = ForegroundColorSpan(Color.GREEN)
我正在动态格式化字符串,如 Android 文档中的以下示例:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
然后我这样设置值:
var text = getString(R.string.welcome_messages, username, mailCount)
如何为 username 设置绿色,为 mailCount 设置红色?
我也需要它适用于多个语言环境。所以我不能自己硬编码位置。
之前我把这个字符串分成4个部分,然后可以很容易地使用SpannableBuilder
来改变颜色。
HTML 和 CDATA 不合适。我们需要为 Android 和 iOS.
保留相同的字符串声明字符串
<string name="string_formatted"><![CDATA[ Hello, <font color=#145A14> %1$s!</font> You have %2$d new messages]]></string>
在Activity
TextView tv = findViewById(R.id.mytext);
tv.setText(Html.fromHtml(getString(R.string.html_formatted,"XYZ", 5)));
您可以根据需要使用 SpannableString
和 setSpan
。
<string name="welcome_message">Hello, %1$s! You have %2$d new messages.</string>
void setSpannableTextWithColor(TextView view, int resourceId, String username, int userColor, int messageCount, int countColor) {
String fulltext = getString(resourceId, username, messageCount);
view.setText(fulltext, TextView.BufferType.SPANNABLE);
Spannable str = (Spannable) view.getText();
int usernameIndex = fulltext.indexOf(username);
str.setSpan(new ForegroundColorSpan(userColor), usernameIndex, usernameIndex + username.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
int countIndex = fulltext.indexOf(String.valueOf(messageCount));
str.setSpan(new ForegroundColorSpan(countColor), countIndex, countIndex + String.valueOf(messageCount).length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
setSpannableTextWithColor(findViewById(R.id.text_view1), R.string.welcome_message, "Viktor Vostrikov", Color.GREEN, 122, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view2), R.string.welcome_message, "Виктор Востриков", Color.GREEN, 2, Color.RED);
setSpannableTextWithColor(findViewById(R.id.text_view3), R.string.welcome_message, "فيكتور فوستريكوف", Color.GREEN, 2000, Color.RED);
输出:
使用Jetpack core-ktx,可以简洁的写成:
val s = "Beautiful City".toSpannable()
s[0..9] = ForegroundColorSpan(Color.GREEN)