¿Es posible tener marcadores de posición en valores de cadena en los string.xmlque 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.xmlque 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$ses una cadena y%2$des 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 getStringtiene 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 mailCountpará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$sy %2$den 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
Marytiene12añ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);
getStringporque 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$svarias 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. :)
xliffetiquetas alrededor de los especificadores de formato? ¿Qué valor adicional agregan en lugar de usar solo los especificadores %sy %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 valpalabra clave. Ver respuesta de msbodw001