Un recurso de string ofrece strings de texto para tu aplicación con formato y estilo de texto opcionales. Existen tres tipos de recursos que pueden proporcionar strings para tu aplicación:
- String
- Recurso XML que ofrece una sola string.
- Matriz de strings
- Recurso XML que ofrece una matriz de strings.
- Strings de cantidad (plurales)
- Recurso XML que conlleva diferentes strings para brindar pluralización.
Todas las strings pueden aplicar algunos argumentos de formato y lenguaje de marcado de estilo. Para obtener información sobre las strings de formato y estilo, consulta la sección sobre Formato y estilo.
String
Una sola string a la cual se puede hacer referencia desde la aplicación o desde otros archivos de recursos (por ejemplo, un diseño XML).
Nota: Una string es un recurso simple al cual se hace referencia
mediante el valor proporcionado en el atributo name
(no el nombre del archivo XML). De este modo, puedes
combinar recursos de strings con otros recursos simples en el único archivo XML,
debajo de un elemento <resources>
.
- ubicación del archivo:
res/values/filename.xml
El nombre del archivo es arbitrario. Elname
del elemento<string>
se usará como ID del recurso.- tipo de datos del recurso compilado:
- Puntero de recurso para un elemento
String
. - referencia del recurso:
-
En Java:
R.string.string_name
En XML:@string/string_name
- sintaxis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
- elementos:
- ejemplo:
- archivo XML guardado en
res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
Este XML de diseño aplica una string a un objeto View:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
Este código de aplicación recupera una string:
String string =
getString
(R.string.hello);Puedes usar
getString(int)
ogetText(int)
para obtener una string.getText(int)
retendrá todo estilo de texto enriquecido aplicado a la string.
Matriz de strings
Matriz de strings a la cual se puede hacer referencia desde la aplicación.
Nota: Una matriz de strings es un recurso simple al cual se hace referencia
mediante el valor proporcionado en el atributo name
(no el nombre del archivo XML). De
este modo, puedes combinar recursos de matriz de strings con otros recursos simples en el único archivo XML,
debajo de un elemento <resources>
.
- ubicación del archivo:
res/values/filename.xml
El nombre del archivo es arbitrario. Elname
del elemento<string-array>
se usará como ID del recurso.- tipo de datos del recurso compilado:
- Puntero de recurso para un elemento de matriz de
String
. - referencia del recurso:
-
En Java:
R.array.string_array_name
- sintaxis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
- elementos:
- ejemplo:
- archivo XML guardado en
res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="planets_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> </string-array> </resources>
Este código de aplicación obtiene una matriz de strings:
Resources res =
getResources()
; String[] planets = res.getStringArray
(R.array.planets_array);
Strings de cantidad (plurales)
Los diferentes idiomas tienen distintas reglas de concordancia gramatical con la cantidad. En inglés,
por ejemplo, la cantidad 1 es un caso especial. Se escribe “1 book” (1 libro), pero para las demás cantidades se debe
escribir “n books” (n libros). Esta distinción entre singular y plural es muy común; sin embargo, en otros
idiomas, se hacen distinciones más detalladas. El conjunto completo compatible con Android es zero
,
one
, two
, few
, many
y other
.
Las reglas para decidir el caso que se usará para un idioma y una cantidad determinados pueden ser muy complejas,
por lo cual Android te proporciona métodos como
getQuantityString()
para seleccionar
el recurso adecuado para ti.
Si bien históricamente se llamaron “strings de cantidad” (y aún se llaman así en API), las strings
de cantidad solo deben usarse para los plurales. Sería un error usar strings de cantidad para
implementar algo como “Inbox” de Gmail en comparación con “Inbox (12)” cuando existen mensajes no leídos, por
ejemplo. Podría parecer conveniente usar strings de cantidad en lugar de una instrucción if
,
pero es importante tener en cuenta que, en algunos idiomas (como el chino), no se hacen estas distinciones
gramaticales en absoluto, por lo que siempre obtendrás la string other
.
La selección de la string que se debe usar se realiza únicamente según la necesidad gramatical.
En inglés, una string para zero
se ignorará incluso si la cantidad es 0, ya que 0
no es gramaticalmente diferente de 2 o cualquier otro número, excepto 1 (“zero books”, “one book”,
“two books” y así sucesivamente). Por el contrario, en coreano, solo se usará la string other
.
No te confundas por el hecho de que, por ejemplo, two
suena como si solo pudiera aplicarse a
la cantidad 2: un idioma puede requerir que 2, 12, 102 (y así sucesivamente) se traten de manera
similar, pero de forma diferente de otras cantidades. Confía en tu traductor para conocer las distinciones
en las que insiste su idioma.
En ocasiones, es posible evitar las strings de cantidad usando fórmulas de cantidad neutra, por ejemplo “Books: 1” (Libros: 1). Esto hará más fáciles las cosas para ti y tus traductores si se trata de un estilo que se conserva en tu aplicación.
Nota: Una colección de plurales es un recurso simple
al cual se hace referencia en el atributo name
(no el nombre del archivo XML
). Por eso, puedes combinar recursos de plurales con otros recursos simples en un
archivo XML, en un elemento <resources>
.
- ubicación del archivo:
res/values/filename.xml
El nombre del archivo es arbitrario. Elname
del elemento<plurals>
se usará como ID del recurso.- referencia del recurso:
-
En Java:
R.plurals.plural_name
- sintaxis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="plural_name"> <item quantity=["zero" | "one" | "two" | "few" | "many" | "other"] >text_string</item> </plurals> </resources>
- elementos:
- ejemplo:
- archivo XML guardado en
res/values/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <!-- As a developer, you should always supply "one" and "other" strings. Your translators will know which strings are actually needed for their language. Always include %d in "one" because translators will need to use %d for languages where "one" doesn't mean 1 (as explained above). --> <item quantity="one">%d song found.</item> <item quantity="other">%d songs found.</item> </plurals> </resources>
archivo XML guardado en
res/values-pl/strings.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">Znaleziono %d piosenkę.</item> <item quantity="few">Znaleziono %d piosenki.</item> <item quantity="other">Znaleziono %d piosenek.</item> </plurals> </resources>
Código Java:
int count = getNumberOfsongsAvailable(); Resources res =
getResources()
; String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);Cuando se usa el método
getQuantityString()
, debes pasarcount
dos veces si tu string incluye formato de string con un número. Por ejemplo, para la string%d songs found
, el primer parámetro decount
selecciona el plural adecuado y el segundo parámetro decount
se inserta en el marcador de posición%d
. Si tus strings de plural no incluyen formato de string, no es necesario que pases el tercer parámetro agetQuantityString
.
Formato y estilo
A continuación, se mencionan algunos puntos importantes que debes saber sobre cómo dar formato y estilo adecuadamente a tus recursos de strings.
Evitar apóstrofos y comillas
Si tienes un apóstrofo ('
) en tu string, debe
escaparse con una barra invertida (\'
) o disponerse entre
comillas dobles (""
). Por ejemplo, a continuación, se muestran algunas strings que funcionan
y no funcionan:
<string name="good_example">This\'ll work</string> <string name="good_example_2">"This'll also work"</string> <string name="bad_example">This doesn't work</string> <!-- Causes a compile error -->
Si tienes una comilla doble en tu string, se debe escapar
(\"
). Disponer la string entre comillas simples
no funciona.
<string name="good_example">This is a \"good string\".</string> <string name="bad_example">This is a "bad string".</string> <!-- Quotes are stripped; displays as: This is a bad string. --> <string name="bad_example_2">'This is another "bad string".'</string> <!-- Causes a compile error -->
Dar formato a las strings
Si necesitas dar formato a tus strings con String.format(String, Object...)
,
puedes hacerlo disponiendo
tus argumentos de formato en el recurso de strings. Por ejemplo, con el siguiente recurso:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
En este ejemplo, la string de formato tiene dos argumentos: %1$s
es una string y %2$d
es un número decimal. Puedes dar formato a la string con argumentos de tu aplicación, de la siguiente manera:
Resources res = getResources()
;
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
Dar estilo con el lenguaje de marcado HTML
Puedes agregar estilo a tus strings con el lenguaje de marcado HTML. Por ejemplo:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Entre los elementos HTML compatibles se incluyen los siguientes:
<b>
para texto en negrita.<i>
para texto en cursiva.<u>
para texto subrayado.
Es posible que a veces desees crear un recurso de texto con estilo que también se use como string
de formato. Normalmente, esto no funcionará, ya que el método String.format(String, Object...)
seccionará toda la información de
estilo de la string. La solución temporal para esto es escribir las etiquetas HTML con entidades
escapadas, las cuales luego se recuperan con fromHtml(String)
,
después de que se lleva a cabo el formato. Por ejemplo:
- Almacena tu recurso de texto con estilo como una string escapada con HTML:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
En esta string con formato, se agrega un elemento
<b>
. Ten en cuenta que el corchete de apertura está con escape HTML, mediante la anotación<
. - Luego, da formato a la string como siempre, pero también llama a
fromHtml(String)
para convertir el texto HTML en texto con estilo:Resources res =
getResources()
; String text = String.format(res.getString(R.string.welcome_messages), username, mailCount); CharSequence styledText = Html.fromHtml(text);
Debido a que el método fromHtml(String)
dará formato a todas las entidades HTML, asegúrate de
escapar todos los caracteres HTML posibles en las strings que usas con el texto con formato, mediante
htmlEncode(String)
. Por ejemplo, si pasas un argumento de string a
String.format()
que pueda contener caracteres como
“<” o “&”, se deben escapar antes de dar formato, de modo que cuando se pase la string con formato
por fromHtml(String)
los caracteres salgan de la forma en la cual
se escribieron originalmente. Por ejemplo:
String escapedUsername = TextUtil.htmlEncode
(username); Resources res =getResources()
; String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount); CharSequence styledText = Html.fromHtml(text);
Dar estilo con Spannable
Un Spannable
es un objeto de texto al cual puedes dar estilo con
propiedades de tipos de letras, como color y tamaño de las fuentes. Usas
SpannableStringBuilder
para crear
tu texto y, luego, aplicar estilos definidos en el paquete de android.text.style
para el texto.
Puedes usar los siguientes métodos auxiliares para configurar gran parte del trabajo de crear texto de Spannable:
/** * Returns a CharSequence that concatenates the specified array of CharSequence * objects and then applies a list of zero or more tags to the entire range. * * @param content an array of character sequences to apply a style to * @param tags the styled span objects to apply to the content * such as android.text.style.StyleSpan * */ private static CharSequence apply(CharSequence[] content, Object... tags) { SpannableStringBuilder text = new SpannableStringBuilder(); openTags(text, tags); for (CharSequence item : content) { text.append(item); } closeTags(text, tags); return text; } /** * Iterates over an array of tags and applies them to the beginning of the specified * Spannable object so that future text appended to the text will have the styling * applied to it. Do not call this method directly. */ private static void openTags(Spannable text, Object[] tags) { for (Object tag : tags) { text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK); } } /** * "Closes" the specified tags on a Spannable by updating the spans to be * endpoint-exclusive so that future text appended to the end will not take * on the same styling. Do not call this method directly. */ private static void closeTags(Spannable text, Object[] tags) { int len = text.length(); for (Object tag : tags) { if (len > 0) { text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { text.removeSpan(tag); } } }
Los siguientes métodos de bold
, italic
y color
te muestran la manera de llamar los métodos auxiliares a fin de aplicar
estilos definidos en el paquete de android.text.style
. Puedes crear
métodos similares para hacer otros tipos de estilos de texto.
/** * Returns a CharSequence that applies boldface to the concatenation * of the specified CharSequence objects. */ public static CharSequence bold(CharSequence... content) { return apply(content, new StyleSpan(Typeface.BOLD)); } /** * Returns a CharSequence that applies italics to the concatenation * of the specified CharSequence objects. */ public static CharSequence italic(CharSequence... content) { return apply(content, new StyleSpan(Typeface.ITALIC)); } /** * Returns a CharSequence that applies a foreground color to the * concatenation of the specified CharSequence objects. */ public static CharSequence color(int color, CharSequence... content) { return apply(content, new ForegroundColorSpan(color)); }
A continuación, es un ejemplo de la manera de encadenar estos métodos a fin de crear una secuencia de caracteres con diferentes tipos de estilos aplicados a palabras individuales:
// Create an italic "hello, " a red "world", // and bold the entire sequence. CharSequence text = bold(italic(res.getString(R.string.hello)), color(Color.RED, res.getString(R.string.world)));