是否可以在Android中动态将String添加到String.xml?


Answers:


1033

格式化和样式

是的,请参阅字符串资源中的以下内容:格式和样式

如果您需要使用来格式化字符串String.format(String, Object...),则可以通过将format参数放在字符串资源中来实现。例如,使用以下资源:

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

在此的示例格式字符串有两个参数:%1$s是一个字符串,%2$d是一个十进制数字。您可以使用应用程序中的参数来格式化字符串,如下所示:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

基本用法

请注意,getString有一个使用字符串作为格式字符串的重载:

String text = res.getString(R.string.welcome_messages, username, mailCount);

复数

如果需要处理复数,请使用以下命令:

<plurals name="welcome_messages">
    <item quantity="one">Hello, %1$s! You have a new message.</item>
    <item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>

第一个mailCount参数用于确定要使用的格式(单数或复数),其他参数是您的替代:

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

有关更多详细信息,请参见字符串资源:复数


61
实际上没有必要在第一个代码示例中进行String.format调用,Resources.getString()支持格式设置,请参阅:developer.android.com/reference/android/content/res/…、java.lang.Object ...)
Arnaud 2012年

16
对于String.xml中的复数形式,您需要将id设置为R.plurals.welcome_messages而不是R.string.welcome_messages
om252345 2013年

仅返回最后一个项目字符串的复数形式...任何想法如何获取附加字符串。
CoDe

1
使用此方法设置字符串格式时,它删除了您可能使用过的所有元标记(例如超链接等),这些标记可能包含在xml字符串文本中
Jonathan

4
字符串代表%1 $ s,十进制代表%2 $ d,整数代表什么?%1,%2的含义是什么?此参数是计数吗?如果我要第三个参数,是否提及%3?
reegan29'2015/

259

补充答案

当我第一次看到%1$s%2$d接受接受的答案时,这没有任何意义。这里有更多解释。

它们被称为格式说明符。在xml字符串中,它们的形式为

%[parameter_index$][format_type] 
  • :百分号标记格式说明符的开始。
  • 参数索引:这是一个数字,后跟一个美元符号。如果你有,你想插入串三个参数,那么他们将被称为1$2$3$。将它们放置在资源字符串中的顺序无关紧要,只需要提供参数的顺序即可。
  • 格式类型:有很多,你可以格式化事情的方式(请参阅文档)。这是一些常见的:

    • s
    • d 十进制整数
    • f 浮点数

我们将创建以下格式的字符串,其中以编程方式插入灰色部分。

我妹妹Mary12岁。

string.xml

<string name="my_xml_string">My sister %1$s is %2$d years old.</string>

MyActivity.java

String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);

笔记

  • 我可以使用,getString因为我处于活动状态。context.getResources().getString(...)如果不可用,可以使用。
  • String.format() 还将格式化字符串。
  • 1$2$术语并不需要按顺序使用做。也就是说,2$可以先于1$。在将应用国际化为使用不同字序的语言时,这很有用。
  • %1$s如果要重复,可以在xml中多次使用格式说明符。
  • 使用%%以获得实际%的性格。
  • 有关更多详细信息,请阅读以下有用的教程:Android SDK快速提示:格式化资源字符串

125

当您想使用实际的strings.xml文件中的参数而不使用任何Java代码时:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "WhereDat">
  <!ENTITY author "Oded">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

这不适用于资源文件,即必须将变量复制到需要它们的每个XML文件中。


除了在<![CDATA [&param; ]]>
Hermann Poilpre

2
有什么方法可以<!DOCTYPE... ]>在单独的文件中定义零件并将其包含在多个资源文件中?有什么技巧可以做到这一点?
prom85 '18 -10-20

18

一直在寻找相同的东西,终于找到了以下非常简单的解决方案。最佳:开箱即用。
1.更改您的字符串资源:

<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have 
<xliff:g name="count">%d</xliff:g> new messages.</string>

2.使用字符串替换:

c.getString(R.string.welcome_messages,name,count);

其中c是上下文,name是一个字符串变量,并计算 int变量

您需要包括

<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

在您的res / strings.xml中。为我工作。:)


2
什么是点xliff周围的格式说明标签?与仅使用%sand %d指示符相反,它们还增加了什么附加值?
理查德·勒·马修里尔

xliff标记中的“ name”属性只是一种向翻译者提示将在其中进行替换的方法。有时很难猜测“%s”的含义。
hugomg

3

在Kotlin中,您只需要像这样设置字符串值:

<string name="song_number_and_title">"%1$d ~ %2$s"</string>

在布局上创建文本视图:

<TextView android:id="@+id/song_number_and_title"/>

如果使用Anko,请在代码中执行以下操作:

val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))  

您可能需要从应用程序上下文中获取资源。


5
那与Java示例有什么不同?我认为没有什么不同
Janusz Hain '18


1

在res / values / string.xml中

<resources>
    <string name="app_name">Hello World</string>
    <string name="my_application">Application name: %s, package name: %s</string>
</resources>

用Java代码

String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);


1

如果要写百分比(%),请复制它:

<string name="percent">%1$d%%</string>

label.text = getString(R.string.percent, 75) // Output: 75%.

如果您只写简单%1$d%,则会得到错误:Format string 'percent' is not a valid format string so it should not be passed to String.format


0

是! 您无需编写任何Java / Kotlin代码,而只需编写XML,就可以使用我创建的这个小库,在构建时就可以这样做,因此您的应用程序不会受到它的影响:https : //github.com/LikeTheSalad/android -字符串参考

用法

您的字符串:

<resources>
    <string name="app_name">My App Name</string>
    <string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>

构建后生成的字符串:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

0

Kotlin的直接解决方案:

strings.xml

<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>

kotlinActivityORFragmentFile.kt:

val username = "Andrew"
val products = 1000
val text: String = String.format(
      resources.getString(R.string.customer_message), username, products )

0

在您的字符串文件中使用

<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>

并在您的代码中相应地使用

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));

-1

Kotlin版本已接受的答案...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

3
更正确的方法是使用resources.getString(int, ... args)带参数的方法代替String.format。此代码中也没有kotlin细节,val关键字除外。请参阅msbodw001的答案
dant3 2007年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.