是否可以在 strings.xml 中为运行时值提供占位符?

发布于 2024-09-17 19:32:18 字数 149 浏览 8 评论 0原文

string.xml 中的字符串值中是否可以包含可以在运行时赋值的占位符?

例子:

一些字符串PLACEHOLDER1一些更多的字符串

Is it possible to have placeholders in string values in string.xml that can be assigned values at run time?

Example:

some string PLACEHOLDER1 some more string

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

虚拟世界 2024-09-24 19:32:18

格式和样式

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

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

你好,%1$s!您有 %2$d 条新消息。

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

资源 res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), 用户名, 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);

请参阅字符串资源:复数 了解更多详细信息。

Formatting and Styling

Yes, see the following from String Resources: Formatting and Styling

If you need to format your strings using String.format(String, Object...), then you can do so by putting your format arguments in the string resource. For example, with the following resource:

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

In this example, the format string has two arguments: %1$s is a string and %2$d is a decimal number. You can format the string with arguments from your application like this:

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

Basic Usage

Note that getString has an overload that uses the string as a format string:

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

Plurals

If you need to handle plurals, use this:

<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>

The first mailCount param is used to decide which format to use (single or plural), the other params are your substitutions:

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

See String Resources: Plurals for more details.

慵挽 2024-09-24 19:32:18

补充答案

当我第一次在接受的答案中看到 %1$s%2$d 时,它毫无意义。这里有更多的解释。

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

%[parameter_index$][format_type] 
  • %:百分号标记格式说明符的开头。

  • 参数索引:这是一个数字,后跟一个美元符号。如果您想要插入到字符串中的三个参数,那么它们将被称为 1$2$3$。您将它们放置在资源字符串中的顺序并不重要,重要的是您提供参数的顺序。

  • 格式类型:有很多方式可以格式化内容(请参阅文档)。以下是一些常见的:

  • s string

  • d 十进制整数

  • f 浮点数

示例

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

我的妹妹玛丽已经12岁了。

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 因为我处于 Activity 中。如果不可用,您可以使用context.getResources().getString(...)
  • String.format() 还将格式化字符串。
  • 1$2$ 术语不需要按该顺序使用。也就是说,2$ 可以出现在 1$ 之前。当针对使用不同词序的语言对应用程序进行国际化时,这非常有用。
  • 如果您想重复,可以在 xml 中多次使用类似 %1$s 的格式说明符。
  • 使用 %% 获取实际的 % 字符。
  • 有关更多详细信息,请阅读以下有用的教程:Android SDK 快速提示:格式化资源字符串

Supplemental Answer

When I first saw %1$s and %2$d in the accepted answer, it made no sense. Here is a little more explanation.

They are called format specifiers. In the xml string they are in the form of

%[parameter_index$][format_type] 
  • %: The percent sign marks the beginning of the format specifier.

  • parameter index: This is a number followed by a dollar sign. If you had three parameters that you wanted to insert into the string, then they would be called 1$, 2$, and 3$. The order you place them in the resource string doesn't matter, only the order that you supply the parameters.

  • format type: There are a lot of ways that you can format things (see the documentation). Here are some common ones:

  • s string

  • d decimal integer

  • f floating point number

Example

We will create the following formatted string where the gray parts are inserted programmatically.

My sister Mary is 12 years old.

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);

Notes

  • I could use getString because I was in an Activity. You can use context.getResources().getString(...) if it is not available.
  • String.format() will also format a String.
  • The 1$ and 2$ terms don't need to be used in that order. That is, 2$ can come before 1$. This is useful when internationalizing an app for languages that use a different word order.
  • You can use a format specifier like %1$s multiple times in the xml if you want to repeat it.
  • Use %% to get the actual % character.
  • For more details read the following helpful tutorial: Android SDK Quick Tip: Formatting Resource Strings
惯饮孤独 2024-09-24 19:32:18

当您想要使用实际 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 文件中。

When you want to use a parameter from the actual strings.xml file without using any Java code:

<?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>

This does not work across resource files, i.e. variables must be copied into each XML file that needs them.

っ左 2024-09-24 19:32: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 是一个字符串变量和 count 你的 int 变量

你需要包含

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

在你的 res/strings.xml 中。
对我有用。 :)

Was looking for the same and finally found the following very simple solution. Best: it works out of the box.
1. alter your string ressource:

<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. use string substitution:

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

where c is the Context, name is a string variable and count your int variable

You'll need to include

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

in your res/strings.xml.
Works for me. :)

岁月静好 2024-09-24 19:32:18

如果你想写百分比 (%),请重复它:

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

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

如果你简单地写 %1$d%,你会得到错误:格式字符串 'percent' 不是有效的格式字符串因此不应将其传递给 String.format

或者使用 formatted=false"

If you want to write percent (%), duplicate it:

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

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

If you write simply %1$d%, you will get the error: Format string 'percent' is not a valid format string so it should not be passed to String.format.

Or use formatted=false" instead.

熟人话多 2024-09-24 19:32:18

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

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

在布局上创建一个文本视图:

<TextView android:text="@string/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))  

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

In Kotlin you just need to set your string value like this:

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

Create a text view on your layout:

<TextView android:text="@string/song_number_and_title"/>

Then do this in your code if you using 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))  

You might need to get your resources from the application context.

箜明 2024-09-24 19:32:18

在您的字符串文件中使用它

<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)));

In your string file use this

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

And in your code use as accordingly

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));
画骨成沙 2024-09-24 19:32:18

对于多语言项目

作为一个曾开发过具有多种不同语言和每个变体配置的主要白标解决方案的人,我可以说有很多事情需要考虑。
抛开文本方向不谈,光是语法就会让你头疼。
例如,项目的顺序是否可以改变,因此

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

是首选

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

,但是一旦您与经常不知道字符串或整数是什么的翻译人员一起工作,更不用说每种类型使用什么格式字符,或者一般人不知道参数在代码中应用的顺序,甚至您自己也忘记了,或者事情发生了变化,必须同时在多个位置进行更新,因此使用 MessageFormat 这样的方法

<string name="welcome_message">Hello, {0}! You have {1} new messages.</string>

MessageFormat(R.string.welcome_message).format("Name", numMessages)

是不可行的要么让非技术人员尝试找出xlift的想法甚至无法接受,那么到目前为止我所知道的最好的解决方案是使用显式的、命名的占位符作为这样

<string name="placeholder_data" translatable="false">DATA</string>
<string name="placeholder_data" translatable="false">$DATA</string>
<string name="placeholder_data" translatable="false">%DATA%</string>

..或其他任何与您的文本不冲突的内容。

虽然您可以像

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY placeholder_data "$DATA">
]>
<string name="text_with_data">Your data is &placeholder_data;.</string>

这样使用 DOCTYPE,但它不适用于每种语言的单独文件。

因此,在您的 main/res/values/strings.xml 中提供这样的占位符和默认字符串

<resources>

    <string name="placeholder_data" translatable="false">$DATA</string>
    <string name="placeholder_error" translatable="false">$ERROR</string>

    <string name="app_name">The App</string>

    <string name="content_loading">loading..</string>
    <string name="content_success">success: $DATA</string>
    <string name="content_error">error: $ERROR</string>

</resources>

,然后在您的变体 variant/res/values-de/strings.xml 中提供

<resources>

    <string name="app_name">Die Applikation</string>

    <string name="content_loading">Ladevorgang..</string>
    <string name="content_success">Erfolg: $DATA</string>
    <string name="content_error">Netzwerkkommunikationsfehler: $ERROR</string>

</resources>

要使用它,请编写类似

    textView.text = when (response) {
        is Data -> getText(content_success).resolveData(response.data)
        is Error -> getText(content_error).resolveError(response.error)
        is Loading -> getText(content_loading)
    }

使用一些辅助函数的内容,例如

    fun CharSequence.resolveData(data: JsonObject) =
        toString().replace(getString(placeholder_data), data.toString())

    fun CharSequence.resolveError(error: Throwable) =
        toString().replace(getString(placeholder_error), error.toString())

简单地为翻译文件和开发提供参考。因此,每个构建风格不应该有一个默认文件。只有单个默认文件,然后是每个语言 x 变体的文件。

现在还有数字语法的问题。这可以通过 plurals 来解决,但是 xml 文件的复杂性再次增加。而且,正如所指出的,zero 并不像人们所期望的那样工作。但由于显示大小限制或 UI 的预渲染图像数量,您可能希望对应用计数进行限制,并且需要显示 99+ 而不是 100代码>.解决方案是使用辅助函数,例如

    fun Context.getText(
        quantity: Int,
        @PluralsRes resIdQuantity: Int,
        @StringRes resIdNone: Int? = null,
        @StringRes resIdMoreThan: Int? = null,
        maxQuantity: Int? = null,
    ): CharSequence {
        if (resIdMoreThan != null && maxQuantity != null && quantity > maxQuantity)
            return getText(resIdMoreThan)
        return if (resIdNone != null && quantity == 0) return getText(resIdNone)
        else resources.getQuantityText(resIdQuantity, quantity)
    }

覆盖和扩展复数解析器的行为。

如果每个变体都有可选功能,则添加一个 res/values/strings-beans.xml ,例如:

<resources>

    <string name="placeholder_name" translatable="false">$NAME</string>
    <string name="placeholder_count" translatable="false">$COUNT</string>

    <string name="beans_content_bean_count_zero">Hello $NAME! You have no beans.</string>
    <string name="beans_content_bean_count_one">Hello $NAME! You have one bean.</string>
    <string name="beans_content_bean_count_many">Hello $NAME! You have $COUNT beans.</string>
    <string name="beans_content_bean_count_more_than_9000">Hello $NAME! You have over $COUNT beans!</string>
    <string name="beans_content_bean_count_two">@string/beans_content_bean_count_many</string>
    <string name="beans_content_bean_count_few">@string/beans_content_bean_count_many</string>
    <string name="beans_content_bean_count_other">@string/beans_content_bean_count_many</string>
    <plurals name="beans_content_bean_count">
        <item quantity="zero">@string/beans_content_bean_count_zero</item>
        <item quantity="one">@string/beans_content_bean_count_one</item>
        <item quantity="two">@string/beans_content_bean_count_two</item>
        <item quantity="few">@string/beans_content_bean_count_few</item>
        <item quantity="many">@string/beans_content_bean_count_many</item>
        <item quantity="other">@string/beans_content_bean_count_other</item>
    </plurals>

</resources>

variant-with-beans/res/value-en/strings- 中的变体beans.xml 只需要包含

<resources>

    <string name="beans_content_bean_count_zero">Hello $NAME! You have no beans.</string>
    <string name="beans_content_bean_count_one">Hello $NAME! You have one bean.</string>
    <string name="beans_content_bean_count_many">Hello $NAME! You have $COUNT beans.</string>
    <string name="beans_content_bean_count_more_than_9000">Hello $NAME! You have over 9000 beans!</string>

</resources>

特定于语言的覆盖,可以在每个文件的基础上提供。
要使用它,代码可以如下所示

    val name = "Bob"
    val beanCount = 3
    val limit = 9000
    text = getText(
        beanCount,
        beans_content_bean_count,
        beans_content_bean_count_zero,
        beans_content_bean_count_more_than_9000,
        limit,
    )
        .resolveCount(beanCount)
        .resolveName(name)

,它解析为输出

    beanCount = 0 -> "Hello Bob! You have no beans."
    beanCount = 1 -> "Hello Bob! You have one bean."
    beanCount = 3 -> "Hello Bob! You have 3 beans."
    beanCount = 9001 -> "Hello Bob! You have over 9000 beans!"

,并且由于语言特定资源文件的简单性,然后可以使用电子表格或您公司自己的服务器端点等的部署工具生成它们。

我希望你喜欢我进入 Android 动态字符串资源世界的令人发狂的旅程,并希望你明白你不是那些必须获得相同功能才能在产品的 iOS 端工作的可怜的傻瓜,根据我的经验,需要 python 脚本来修改。 xcodeproj 文件并生成 swift 代码。

For Multilingual Projects

As someone who has worked on a major white label solution with many and varying languages and configurations per variant, I can say that there's a lot to consider.
Text direction aside, grammar alone can give you some headaches.
For instance can the order of items change thus

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

is to be preferred over

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

but once you work with translators who often don't know what a string or an integer is, let alone what formatting character to use for each type, or people in general who have no idea in what order the parameters are applied in your code, or even you yourself forget that, or things change which then must be updated at multiple places at once, so using MessageFormat like

<string name="welcome_message">Hello, {0}! You have {1} new messages.</string>

MessageFormat(R.string.welcome_message).format("Name", numMessages)

isn't viable either and the idea of having non tech people try to figure out xlift can't even be entertained then the best solution I know so far is to use explicit, named placeholders as such

<string name="placeholder_data" translatable="false">DATA</string>
<string name="placeholder_data" translatable="false">$DATA</string>
<string name="placeholder_data" translatable="false">%DATA%</string>

..or whatever else doesn't conflict with your texts.

And while you could use DOCTYPE like

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY placeholder_data "$DATA">
]>
<string name="text_with_data">Your data is &placeholder_data;.</string>

this will not work with separate files for each language.

Thus in your main/res/values/strings.xml provide the placeholders and default strings like this

<resources>

    <string name="placeholder_data" translatable="false">$DATA</string>
    <string name="placeholder_error" translatable="false">$ERROR</string>

    <string name="app_name">The App</string>

    <string name="content_loading">loading..</string>
    <string name="content_success">success: $DATA</string>
    <string name="content_error">error: $ERROR</string>

</resources>

and then in your variant variant/res/values-de/strings.xml

<resources>

    <string name="app_name">Die Applikation</string>

    <string name="content_loading">Ladevorgang..</string>
    <string name="content_success">Erfolg: $DATA</string>
    <string name="content_error">Netzwerkkommunikationsfehler: $ERROR</string>

</resources>

and to use it, write something like

    textView.text = when (response) {
        is Data -> getText(content_success).resolveData(response.data)
        is Error -> getText(content_error).resolveError(response.error)
        is Loading -> getText(content_loading)
    }

with the use of some helper functions like

    fun CharSequence.resolveData(data: JsonObject) =
        toString().replace(getString(placeholder_data), data.toString())

    fun CharSequence.resolveError(error: Throwable) =
        toString().replace(getString(placeholder_error), error.toString())

for simply the reason of having a reference for the translation files and development. Hence there should not be a default file per build flavor. Only the single default file and then a file per language x variant.

Now there's also the issue of numeric grammar. This can be solved with plurals but here again the complexity of the xml file increases. And, as pointed out, zero does not work as one would expect. But also you may want to have a limit to which your app counts due to display size limitations or number of pre-rendered images for your UI and need to display 99+ instead of 100. A solution would be to use a helper function like

    fun Context.getText(
        quantity: Int,
        @PluralsRes resIdQuantity: Int,
        @StringRes resIdNone: Int? = null,
        @StringRes resIdMoreThan: Int? = null,
        maxQuantity: Int? = null,
    ): CharSequence {
        if (resIdMoreThan != null && maxQuantity != null && quantity > maxQuantity)
            return getText(resIdMoreThan)
        return if (resIdNone != null && quantity == 0) return getText(resIdNone)
        else resources.getQuantityText(resIdQuantity, quantity)
    }

to override and extend the behavior of the plurals resolver.

And if you have optional features per variant then add a res/values/strings-beans.xml like:

<resources>

    <string name="placeholder_name" translatable="false">$NAME</string>
    <string name="placeholder_count" translatable="false">$COUNT</string>

    <string name="beans_content_bean_count_zero">Hello $NAME! You have no beans.</string>
    <string name="beans_content_bean_count_one">Hello $NAME! You have one bean.</string>
    <string name="beans_content_bean_count_many">Hello $NAME! You have $COUNT beans.</string>
    <string name="beans_content_bean_count_more_than_9000">Hello $NAME! You have over $COUNT beans!</string>
    <string name="beans_content_bean_count_two">@string/beans_content_bean_count_many</string>
    <string name="beans_content_bean_count_few">@string/beans_content_bean_count_many</string>
    <string name="beans_content_bean_count_other">@string/beans_content_bean_count_many</string>
    <plurals name="beans_content_bean_count">
        <item quantity="zero">@string/beans_content_bean_count_zero</item>
        <item quantity="one">@string/beans_content_bean_count_one</item>
        <item quantity="two">@string/beans_content_bean_count_two</item>
        <item quantity="few">@string/beans_content_bean_count_few</item>
        <item quantity="many">@string/beans_content_bean_count_many</item>
        <item quantity="other">@string/beans_content_bean_count_other</item>
    </plurals>

</resources>

while the variant in variant-with-beans/res/value-en/strings-beans.xml only needs to contain

<resources>

    <string name="beans_content_bean_count_zero">Hello $NAME! You have no beans.</string>
    <string name="beans_content_bean_count_one">Hello $NAME! You have one bean.</string>
    <string name="beans_content_bean_count_many">Hello $NAME! You have $COUNT beans.</string>
    <string name="beans_content_bean_count_more_than_9000">Hello $NAME! You have over 9000 beans!</string>

</resources>

and language specific overrides can be provided on a per file basis.
To use this, the code can look like this

    val name = "Bob"
    val beanCount = 3
    val limit = 9000
    text = getText(
        beanCount,
        beans_content_bean_count,
        beans_content_bean_count_zero,
        beans_content_bean_count_more_than_9000,
        limit,
    )
        .resolveCount(beanCount)
        .resolveName(name)

which resolves to the outputs

    beanCount = 0 -> "Hello Bob! You have no beans."
    beanCount = 1 -> "Hello Bob! You have one bean."
    beanCount = 3 -> "Hello Bob! You have 3 beans."
    beanCount = 9001 -> "Hello Bob! You have over 9000 beans!"

and due to the resulting simplicity of the language specific resource files, they then can be generated with deployment tools from spread sheets or your company's own server endpoints, etc.

I hope you enjoyed my maddening ride into the world of dynamic string resources for Android and hopefully appreciate that you're not the poor fools having to get the same functionality to work on the iOS side of the product which from my experience required python scripts to modify .xcodeproj files and generate swift code.

残花月 2024-09-24 19:32:18

但是,您还应该阅读 Elias MårtensonAndroid 对“零”的复数处理。对某些值(例如“零”)的解释存在问题。

However, you should also read Elias Mårtenson's answer on Android plurals treatment of “zero”. There is a problem with the interpretation of certain values such as "zero".

偷得浮生 2024-09-24 19:32:18

在 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);

in res/values/string.xml

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

in java code

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);
悸初 2024-09-24 19:32:18

您可以使用 MessageFormat

<string name="customer_address">Wellcome: {0} {1}</string>

在 Java 代码中:

String text = MessageFormat(R.string.customer_address).format("Name","Family");

API 级别 1:

https://developer.android.com/reference/java/text/MessageFormat.html

You can use MessageFormat:

<string name="customer_address">Wellcome: {0} {1}</string>

In Java code :

String text = MessageFormat(R.string.customer_address).format("Name","Family");

API level 1:

https://developer.android.com/reference/java/text/MessageFormat.html

梦纸 2024-09-24 19:32:18

问题的直接 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 )

A Direct Kotlin Solution to the problem:

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 )
凉城凉梦凉人心 2024-09-24 19:32:18

是的!您可以在不编写任何 Java/Kotlin 代码的情况下执行此操作,只需使用我创建的这个小型库(在构建时执行此操作)编写 XML,因此您的应用程序不会受到它的影响: com/LikeTheSalad/android-stem" rel="nofollow noreferrer">https://github.com/LikeTheSalad/android-stem

用法

你的字符串:

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

构建后生成的字符串:

<!-- Auto generated during compilation -->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

Yes! you can do so without writing any Java/Kotlin code, only XML by using this small library I created, which does so at buildtime, so your app won't be affected by it: https://github.com/LikeTheSalad/android-stem

Usage

Your strings:

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

The generated string after building:

<!-- Auto generated during compilation -->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>
最佳男配角 2024-09-24 19:32:18

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

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

Kotlin version of the accepted answer...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文