问题
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
回答1:
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.
回答2:
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$
, and3$
. 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
stringd
decimal integerf
floating point number
Example
We will create the following formatted string where the gray parts are inserted programmatically.
My sister
Mary
is12
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 usecontext.getResources().getString(...)
if it is not available. String.format()
will also format a String.- The
1$
and2$
terms don't need to be used in that order. That is,2$
can come before1$
. 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
回答3:
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.
回答4:
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. :)
回答5:
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".
回答6:
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:id="@+id/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.
回答7:
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);
回答8:
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
回答9:
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-string-reference
Usage
Your strings:
<resources>
<string name="app_name">My App Name</string>
<string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>
The generated string after building:
<!--resolved.xml-->
<resources>
<string name="welcome_message">Welcome to My App Name</string>
</resources>
回答10:
Kotlin version of the accepted answer...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
来源:https://stackoverflow.com/questions/3656371/is-it-possible-dynamically-to-add-string-to-string-xml-in-android