android - 如何格式化字符串然后通过注释改变样式
问题描述
我有 3 个字符串本地化
<string name="tests" formatted="true">Test<annotation font="bold"> testBold %1$s</annotation> end</string>
<string name="tests" formatted="true">Тест<annotation font="bold"> тестБолд %1$s</annotation> конец</string>
<string name="tests" formatted="true">Тест<annotation font="bold"> тестБолд %1$s</annotation> кінець</string>
那么我如何通过注释添加一些参数和修改后的文本。我得到的最大收获就是做这件事
CharSequence t = getResources().getString(R.string.tests, "myValue");//in this case i lose my annotation, but set my argument
//OR
CharSequence t = getText(R.string.tests);//in this case i lose my argument but get style BOLD
public SpannableString textFormattingByTags(CharSequence t) {
SpannedString titleText = new SpannedString(t);
SpannedString titleText = (SpannedString) getText(R.string.tests);
Annotation[] annotations = titleText.getSpans(0, titleText.length(), Annotation.class);
SpannableString spannableString = new SpannableString(titleText);
for (Annotation annotation : annotations) {
if (annotation.getKey().equals("font")) {
String fontName = annotation.getValue();
if (fontName.equals("bold")) {
spannableString.setSpan(new CustomTypefaceSpan("",fontBold),
titleText.getSpanStart(annotation),
titleText.getSpanEnd(annotation),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
return spannableString;
}
结果在第一种情况下,我在第二个“Test testBold %1$s end”中得到“Test testBold MyValue end”。谁有一些想法?
解决方案
1. 将参数转换为注解
你的字符串:
<string name="tests" formatted="true">Test<annotation font="bold"> testBold %1$s</annotation> end</string>
变成:
<string name="tests">Test<annotation font="bold"> testBold <annotation arg="0">%1$s</annotation></annotation> end</string>
2. 从资源创建 SpannableStringBuilder
val text = context.getText(R.string.tests) as SpannedString
val spannableText = SpannableStringBuilder(text)
3. 首先应用所有 arg 注释
一个示例实现:
fun SpannableStringBuilder.applyArgAnnotations(vararg args: Any) {
val annotations = this.getSpans(0, this.length, Annotation::class.java)
annotations.forEach { annotation ->
when (annotation.key) {
"arg" -> {
val argIndex = Integer.parseInt(annotation.value)
when (val arg = args[argIndex]) {
is String -> {
this.replace(
this.getSpanStart(annotation),
this.getSpanEnd(annotation),
arg
)
}
}
}
}
}
}
传入参数:
spannableText.applyArgAnnotations("myValue")
4. 应用剩余的注释
spannableText.applyAnnotations()
textView.text = spannableText
5. 结果
测试testBold myValue end
编辑
创建了一个小库来抽象这种行为 - https://github.com/veritas1/tinytextstyler
推荐阅读
- r - 有没有办法在不使下游目标无效的情况下将 file_in 输入的绝对路径更改为 drake?
- javascript - Laravel newly added javascript files give an error net::ERR_ABORTED 404 (Not Found)
- c# - 使用 NLOG 时无法解析服务时缺少详细信息
- c++ - (C++) 异常未处理 - 无效向量
下标 - node.js - 如何使用 express 将我的 mongoDB 查询显示为 json?
- r - 如何使用 barplot() 手动分配沿 x 轴的条形位置?
- c# - 获取计划返回 401 - 未经授权
- php - 如何在 PHP 中分配具有多个返回的变量?
- java - 使用 buffreader 进行 JAva 编程
- javascript - Trouble with Axios post request in basic MERN stack app