如何格式化字符串然后通过注解改变样式
How formatted string and then change style by annotations
我有 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 MyValue end" "Test testBold %1$s end"。谁有什么想法?
如何更改此代码
<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>
进入
<string name="tests" formatted="true">Test<b> testBold %1$s</b> end</string>
<string name="tests" formatted="true">Тест<b> тестБолд %1$s</b> конец</string>
<string name="tests" formatted="true">Тест<b> тестБолд %1$s</b> кінець</string>
你可以像这样使用它
Spanned result = Html.fromHtml(getString(R.string.tests, "testing"));
textView.setText(result);
其他样式包括:
Tags Format
--------------------------
b, strong Bold
i, em, cite, dfn Italics
u Underline
sub Subtext
sup Supertext
big Big
small Small
tt Monospace
h1 ... h6 Headlines
img Image
font Font face and color
blockquote For longer quotes
a Link
div, p Paragraph
br Linefeed
原来你不能使用 getText(),你可以在 the documentation.
中找到相关信息
Typeface fontBold = Typeface.createFromAsset(getAssets(), "fonts/Trebuchet_MS_Bold.ttf");
String s = getResources().getString(R.string.error_date, "20.02.2019", "25.02.2019");
SpannableStringBuilder spannableString = new SpannableStringBuilder(s);
Integer first1 = null;
Integer first2 = null;
Integer last1 = null;
Integer last2 = null;
int digits = 0;
char[] crs = s.toCharArray();
for (int i = 0; i < crs.length; i++) {
if (Character.isDigit(crs[i]) && digits != 8) {
if (first1 == null) {
first1 = i;
}
last1 = i;
digits++;
continue;
}
if (Character.isDigit(crs[i])) {
if (first2 == null) {
first2 = i;
}
last2 = i;
}
}
spannableString.setSpan(new CustomTypefaceSpan("", fontBold), first1, last1 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new CustomTypefaceSpan("", fontBold), first2, last2 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(getInstance());
builder.setTitle("test");
builder.setMessage(spannableString);
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
getLoaderManager().destroyLoader(LOADER_SOE_BILLING_ID);
}
});
android.support.v7.app.AlertDialog alert = builder.create();
alert.show();
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。首先应用所有参数注释
示例实现:
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.结果
Test testBold myValue end
编辑
创建了一个小库来抽象此行为 - https://github.com/veritas1/tinytextstyler
我有 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 MyValue end" "Test testBold %1$s end"。谁有什么想法?
如何更改此代码
<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>
进入
<string name="tests" formatted="true">Test<b> testBold %1$s</b> end</string>
<string name="tests" formatted="true">Тест<b> тестБолд %1$s</b> конец</string>
<string name="tests" formatted="true">Тест<b> тестБолд %1$s</b> кінець</string>
你可以像这样使用它
Spanned result = Html.fromHtml(getString(R.string.tests, "testing"));
textView.setText(result);
其他样式包括:
Tags Format -------------------------- b, strong Bold i, em, cite, dfn Italics u Underline sub Subtext sup Supertext big Big small Small tt Monospace h1 ... h6 Headlines img Image font Font face and color blockquote For longer quotes a Link div, p Paragraph br Linefeed
原来你不能使用 getText(),你可以在 the documentation.
中找到相关信息Typeface fontBold = Typeface.createFromAsset(getAssets(), "fonts/Trebuchet_MS_Bold.ttf");
String s = getResources().getString(R.string.error_date, "20.02.2019", "25.02.2019");
SpannableStringBuilder spannableString = new SpannableStringBuilder(s);
Integer first1 = null;
Integer first2 = null;
Integer last1 = null;
Integer last2 = null;
int digits = 0;
char[] crs = s.toCharArray();
for (int i = 0; i < crs.length; i++) {
if (Character.isDigit(crs[i]) && digits != 8) {
if (first1 == null) {
first1 = i;
}
last1 = i;
digits++;
continue;
}
if (Character.isDigit(crs[i])) {
if (first2 == null) {
first2 = i;
}
last2 = i;
}
}
spannableString.setSpan(new CustomTypefaceSpan("", fontBold), first1, last1 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new CustomTypefaceSpan("", fontBold), first2, last2 + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(getInstance());
builder.setTitle("test");
builder.setMessage(spannableString);
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
getLoaderManager().destroyLoader(LOADER_SOE_BILLING_ID);
}
});
android.support.v7.app.AlertDialog alert = builder.create();
alert.show();
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。从资源
创建SpannableStringBuilderval text = context.getText(R.string.tests) as SpannedString
val spannableText = SpannableStringBuilder(text)
3。首先应用所有参数注释
示例实现:
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.结果
Test testBold myValue end
编辑
创建了一个小库来抽象此行为 - https://github.com/veritas1/tinytextstyler