¿Es posible tener marcadores de posición en valores de cadena en los string.xml
que se puedan asignar valores en tiempo de ejecución?
Ejemplo:
algo de cuerda PLACEHOLDER1 algo más de cuerda
¿Es posible tener marcadores de posición en valores de cadena en los string.xml
que se puedan asignar valores en tiempo de ejecución?
Ejemplo:
algo de cuerda PLACEHOLDER1 algo más de cuerda
Respuestas:
Sí, consulte lo siguiente en Recursos de cadena: formato y estilo
Si necesita formatear sus cadenas usando
String.format(String, Object...)
, entonces puede hacerlo colocando sus argumentos de formato en el recurso de cadena. Por ejemplo, con el siguiente recurso:<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
En este ejemplo, la cadena de formato tiene dos argumentos:
%1$s
es una cadena y%2$d
es un número decimal. Puede formatear la cadena con argumentos de su aplicación de esta manera:Resources res = getResources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
Tenga en cuenta que getString
tiene una sobrecarga que usa la cadena como una cadena de formato:
String text = res.getString(R.string.welcome_messages, username, mailCount);
Si necesita manejar plurales, use esto:
<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>
El primer mailCount
parámetro se usa para decidir qué formato usar (simple o plural), los otros parámetros son sus sustituciones:
Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);
Ver Recursos de cadena: Plurales para más detalles.
Cuando vi por primera vez %1$s
y %2$d
en la respuesta aceptada, no tenía sentido. Aquí hay un poco más de explicación.
Se llaman especificadores de formato. En la cadena xml están en forma de
%[parameter_index$][format_type]
1$
, 2$
y 3$
. No importa el orden en que los coloque en la cadena de recursos, solo el orden en que proporciona los parámetros.tipo de formato : hay muchas formas de formatear las cosas ( consulte la documentación ). Aquí hay algunos comunes:
s
cuerdad
entero decimalf
número de coma flotanteCrearemos la siguiente cadena formateada donde las partes grises se insertan mediante programación.
Mi hermana
Mary
tiene12
años
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
porque estaba en una Actividad. Puedes usarcontext.getResources().getString(...)
si no está disponible.String.format()
también formateará una cadena.1$
y 2$
términos no necesita ser utilizado en ese orden. Es decir, 2$
puede venir antes 1$
. Esto es útil al internacionalizar una aplicación para idiomas que usan un orden de palabras diferente.%1$s
varias veces en el xml si desea repetirlo.%%
para obtener el %
personaje real .Cuando desee utilizar un parámetro del archivo strings.xml real sin utilizar ningún código 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>
Esto no funciona en todos los archivos de recursos, es decir, las variables deben copiarse en cada archivo XML que las necesite.
<!DOCTYPE... ]>
parte en un archivo separado e incluirlo en múltiples archivos de recursos? ¿Algún truco para lograr esto?
Estaba buscando lo mismo y finalmente encontré la siguiente solución muy simple. Lo mejor: funciona fuera de la caja.
1. altere su recurso de cadena:
<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. usar sustitución de cadena:
c.getString(R.string.welcome_messages,name,count);
donde c es el contexto, el nombre es una variable de cadena y cuenta su variable int
Tendrás que incluir
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">
en su res / strings.xml. Funciona para mi. :)
xliff
etiquetas alrededor de los especificadores de formato? ¿Qué valor adicional agregan en lugar de usar solo los especificadores %s
y %d
?
En Kotlin solo necesita establecer su valor de cadena de esta manera:
<string name="song_number_and_title">"%1$d ~ %2$s"</string>
Cree una vista de texto en su diseño:
<TextView android:id="@+id/song_number_and_title"/>
Luego haga esto en su código si está usando 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))
Es posible que necesite obtener sus recursos del contexto de la aplicación.
Sin embargo, también debe leer la respuesta de Elias Mårtenson sobre el tratamiento plural de Android de "cero" . Hay un problema con la interpretación de ciertos valores como "cero".
en res / values / string.xml
<resources>
<string name="app_name">Hello World</string>
<string name="my_application">Application name: %s, package name: %s</string>
</resources>
en código 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);
Puedes usar MessageFormat
:
<string name="customer_address">Wellcome: {0} {1}</string>
En código Java:
String text = MessageFormat(R.string.customer_address).format("Name","Family");
Nivel API 1:
https://developer.android.com/reference/java/text/MessageFormat.html
Si desea escribir porcentaje (%), duplíquelo:
<string name="percent">%1$d%%</string>
label.text = getString(R.string.percent, 75) // Output: 75%.
Si se escribe simplemente %1$d%
, obtendrá el error: Format string 'percent' is not a valid format string so it should not be passed to String.format
.
¡Si! puede hacerlo sin escribir ningún código Java / Kotlin, solo XML utilizando esta pequeña biblioteca que creé, que lo hace en el momento de la compilación, para que su aplicación no se vea afectada por ella: https://github.com/LikeTheSalad/android -cadena-referencia
Uso
Sus cuerdas:
<resources>
<string name="app_name">My App Name</string>
<string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>
La cadena generada después de construir:
<!--resolved.xml-->
<resources>
<string name="welcome_message">Welcome to My App Name</string>
</resources>
Una solución directa de Kotlin al problema:
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 )
En su archivo de cadena use esto
<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>
Y en su código use como corresponda
coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
, rewardPoints.getConversion_rate(), getString(R.string.rs)));
Versión de Kotlin de la respuesta aceptada ...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
resources.getString(int, ... args)
método con argumentos en lugar de String.format
. Tampoco hay detalles específicos de kotlin en este código, aparte de la val
palabra clave. Ver respuesta de msbodw001