我有两个字符串资源:
<string name="give_us_feedback">Give us feedback at %1$s if you want to make the app even better!</string>
<string name="email">[email protected]</string>
我想将电子邮件部分的样式设置为蓝色并带有下划线,以指示用户可以单击它(整个 TextView,而不仅仅是电子邮件文本)。我知道使用 SpannableString 为文本着色,但当我通过 getString(int resId, Object... formatArgs) 组合两个字符串时,它似乎不起作用,大概是因为 getString() 将执行强制转换或 .toString () 在正在发送的对象上。这是不起作用的:
TextView emailTV = new TextView(this);
SpannableString email = new SpannableString(getString(R.string.email));
email.setSpan(new UnderlineSpan(), 0, email.length() - 1, 0);
email.setSpan(new ForegroundColorSpan(Color.BLUE), 0, email.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
String feedback = getString(R.string.give_us_feedback, email);
emailTV.setText(feedback);
有什么想法吗?
有点棘手。转换回字符序列 (
String feedback = getString(R.string.give_us_feedback, email);
) 会使 Spannable
消失。尝试这种方式(您想检查字符串中的正确索引)
String emailString = getString(R.string.email);
String feedback = getString(R.string.give_us_feedback, emailString);
SpannableString email = new SpannableString(feedback);
int startIndex = feedBack.indexOf(emailString);
int endIndex = startIndex + emailString.length();
email.setSpan(new UnderlineSpan(), startIndex, endIndex, 0);
email.setSpan(new ForegroundColorSpan(Color.BLUE), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
emailTV.setText(email);
如果您的字符串已包含与参数相同的文本,则上述答案不起作用。
这就是我所做的(在 Kotlin 中)。我通过在字符串资源中搜索文字参数文本来获取参数的起始索引。这是使用正则表达式的情况。
val text = getString(R.string.id)
val textWithArgs = getString(R.string.id, argument)
// Searches for the start index of %1$s
val startIndex = """%1${"\\$"}s""".toRegex().find(text)?.range?.start
val endIndex = startIndex?.plus(argument.length)
val styledText = if (startIndex == null || endIndex == null) {
textWithArgs
} else {
SpannableString(textWithArgs).apply {
setSpan(
ForegroundColorSpan(
ContextCompat.getColor(
context,
R.color.id
)
), startIndex, endIndex, 0
)
}
}
我写了一个方法来处理它。
是一个参数,用于切换是否从向前或向后搜索字符串,因为这只会突出显示第一次出现的情况。isSearchForward
private fun highlightKeywords(
highlightColor: Int,
message: String,
keyword: String?,
isSearchForward: Boolean? = true
): SpannableString {
val spannableString = SpannableString(message)
if (!keyword.isNullOrBlank()) {
val startIndex = if (isSearchForward == true) {
message.indexOf(keyword)
} else {
message.lastIndexOf(keyword)
}
val endIndex = startIndex + keyword.length
spannableString.setSpan(UnderlineSpan(), startIndex, endIndex, 0)
spannableString.setSpan(
ForegroundColorSpan(highlightColor),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
return spannableString
}
您可以使用我在here的答案,因此您的代码如下:
val email:SpannableString
... - prepare the email variable
val feedback = SpanFormatter.format(getString(R.string.give_us_feedbac),email)