假设您有以下字符串:
String s = "The cold hand reaches for the %1$s %2$s Ellesse's";
String old = "old";
String tan = "tan";
String formatted = String.format(s,old,tan); //"The cold hand reaches for the old tan Ellesse's"假设您希望以这个字符串结束,但也要为任何单词设置一个特定的Span,由String.format替换。
例如,我们还想做以下工作:
Spannable spannable = new SpannableString(formatted);
spannable.setSpan(new StrikethroughSpan(), oldStart, oldStart+old.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new ForegroundColorSpan(Color.BLUE), tanStart, tanStart+tan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);是否有可靠的方法来了解old和tan的起始指数?
请注意,只要搜索“old”,就会在“冷”中返回“old”,这样就不起作用了。
我猜,有效的方法是事先搜索%[0-9]$s,并计算String.format中的替换项的偏移量。不过,这似乎是一个令人头痛的问题,我怀疑可能会有一种类似于String.format的方法,它可以提供更多关于其格式细节的信息。嗯,有吗?
发布于 2014-01-05 18:35:31
像这样使用Spannable是一个令人头痛的问题--这可能是最直接的方法:
String s = "The cold hand reaches for the %1$s %2$s Ellesse's";
String old = "<font color=\"blue\">old</font>";
String tan = "<strike>tan</strike>";
String formatted = String.format(s,old,tan); //The cold hand reaches for the <font color="blue">old</font> <strike>tan</strike> Ellesse's
Spannable spannable = Html.fromHtml(formatted);问题:这不包含在StrikethroughSpan中。为了制作StrikethroughSpan,我们从这个问题那里借用了一个定制的TagHandler。
Spannable spannable = Html.fromHtml(text,null,new MyHtmlTagHandler());MyTagHandler:
public class MyHtmlTagHandler implements Html.TagHandler {
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
if (tag.equalsIgnoreCase("strike") || tag.equals("s")) {
processStrike(opening, output);
}
}
private void processStrike(boolean opening, Editable output) {
int len = output.length();
if (opening) {
output.setSpan(new StrikethroughSpan(), len, len, Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, StrikethroughSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
if (where != len) {
output.setSpan(new StrikethroughSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private Object getLast(Editable text, Class kind) {
Object[] objs = text.getSpans(0, text.length(), kind);
if (objs.length == 0) {
return null;
} else {
for (int i = objs.length; i > 0; i--) {
if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) {
return objs[i - 1];
}
}
return null;
}
}
}发布于 2014-11-30 07:13:31
我已经创建了使用可扩展的String.format。下载并使用它,就像正常版本一样。在您的例子中,您将在格式说明符周围放置跨度(可能使用strings.xml)。在输出中,无论那些说明符被替换为什么,它们都会出现。
发布于 2019-06-14 13:25:31
我制作了简单的Kotlin扩展函数,可以解决String.format跨范围的问题:
fun Context.getStringSpanned(@StringRes resId: Int, vararg formatArgs: Any): Spanned {
var lastArgIndex = 0
val spannableStringBuilder = SpannableStringBuilder(getString(resId, *formatArgs))
for (arg in formatArgs) {
val argString = arg.toString()
lastArgIndex = spannableStringBuilder.indexOf(argString, lastArgIndex)
if (lastArgIndex != -1) {
(arg as? CharSequence)?.let {
spannableStringBuilder.replace(lastArgIndex, lastArgIndex + argString.length, it)
}
lastArgIndex += argString.length
}
}
return spannableStringBuilder
}https://stackoverflow.com/questions/20936901
复制相似问题