Um recurso de string fornece strings de texto para seu aplicativo com estilo e formatação de texto opcionais. Existem três tipos de recursos que podem fornecer strings ao seu aplicativo:
- String
- Recurso XML que fornece uma só string.
- Matriz de strings
- Recurso XML que fornece uma matriz de strings.
- Strings de quantidade (plurais)
- Recurso XML que contém diferentes strings para pluralização.
Todas as strings podem aplicar algumas marcações de estilo e argumentos de formatação. Para saber mais sobre estilos e formatação de strings, consulte a seção sobre Formatação e estilo.
String
É uma string única que pode ser referenciada do código do aplicativo (como uma função combinável) ou de outros arquivos de recursos.
- localização do arquivo:
res/values/filename.xml
O nome do arquivo é arbitrário. Onamedo elemento<string>é usado como o ID do recurso.- tipo de dados do recurso compilado:
- Ponteiro do recurso para um
String. - referência de recurso:
-
Em Kotlin:
R.string.string_name
Em XML:@string/string_name - Sintaxe:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
- elementos:
- exemplo:
- Arquivo XML salvo em
res/values/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
Este código do aplicativo extrai uma string de dentro de um elemento combinável com
stringResource():@Composable fun Greeting() { Text(text = stringResource(R.string.hello)) }
Observação:para extrair uma string fora de uma função combinável, use
Você também pode referenciar recursos de string de outros arquivos XML, comocontext.getString(R.string.hello).AndroidManifest.xml:<activity android:name=".MainActivity" android:label="@string/hello" />
Matriz de strings
É a matriz de strings que pode ser referenciada pelo aplicativo.
- localização do arquivo:
res/values/filename.xml
O nome do arquivo é arbitrário. Onamedo elemento<string-array>é usado como o ID do recurso.- tipo de dados do recurso compilado:
- Ponteiro de recurso para uma matriz de
Strings. - referência de recurso:
-
Em Kotlin:
R.array.string_array_name
Em XML:@[package:]array/string_array_name - Sintaxe:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
- elementos:
- exemplo:
- Arquivo XML salvo em
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 do aplicativo extrai uma matriz de strings de dentro de um elemento combinável com
stringArrayResource():@Composable fun PlanetList() { val planets: Array
= stringArrayResource(R.array.planets_array) // Render the array, e.g. inside a LazyColumn. } Observação:para recuperar uma matriz de strings fora de uma função combinável, use
context.resources.getStringArray(R.array.planets_array).
Strings de quantidade (plurais)
Diferentes idiomas têm diferentes regras de concordância gramatical de quantidade. Em inglês, por exemplo, a quantidade 1 é um caso especial. Escrevemos "1 book" (1 livro), mas, para qualquer outra quantidade, "n books" (n livros). Essa distinção
entre singular e plural é muito comum, mas outros idiomas fazem distinções
mais precisas. O conjunto completo permitido pelo Android é zero, one, two, few,
many e other.
As regras para decidir qual caso usar para determinado idioma e quantidade podem
ser muito complexas. Por isso, o Android fornece métodos como
pluralStringResource() para selecionar o recurso apropriado para você.
Apesar de serem historicamente conhecidas como "strings de quantidade" (ainda chamadas assim na API),
elas precisam ser usadas somente para plurais. Seria um erro usar strings de quantidade para implementar algo como a "Caixa de entrada" do Gmail em vez de "Caixa de entrada (12)" quando houver mensagens não lidas, por exemplo. Pode parecer
conveniente usar strings de quantidade em vez de uma instrução if, mas é
importante observar que alguns idiomas (como o chinês) não fazem essas
distinções gramaticais. Por isso, você sempre vai receber a string other.
A seleção da string é feita exclusivamente com base na necessidade gramatical. Em inglês, uma string para zero é ignorada mesmo que a quantidade seja
0, porque 0 não é gramaticalmente diferente de 2 ou de qualquer outro número, exceto 1
("zero books", "one book", "two books" e assim por diante). Por outro lado, em coreano
apenas a string other é usada.
Não se engane pelo fato de que, por exemplo, two parece ser aplicável somente para
a quantidade 2: um idioma pode exigir que 2, 12, 102 (e assim por diante) sejam
tratados da mesma forma, mas de forma diferente de outras quantidades. Converse com um tradutor para identificar quais são as distinções
obrigatórias de cada idioma.
Se a mensagem não tiver um número de quantidade, provavelmente não é uma boa opção para um plural. Por exemplo, em lituano, a forma singular é usada para 1 e 101. Portanto, "1 livro" é traduzido como "1 knyga", e "101 livros" é traduzido como "101 knyga". Já "um livro" é "knyga" e "vários livros" é "daug knygų". Se uma mensagem no plural em inglês contiver "a book" (singular) e "many books" (plural) sem o número real, ela poderá ser traduzida como "knyga" (um livro)/"daug knygų" (muitos livros), mas, com as regras do lituano, ela vai mostrar "knyga" (um livro), quando o número for 101.
Geralmente, é possível evitar strings de quantidade usando formulações de quantidade neutra, como "Livros: 1". Isso vai facilitar seu trabalho e o dos tradutores, caso seja um estilo compatível com seu aplicativo.
Na API 24 ou versões mais recentes, é possível usar a classe ICU MessageFormat,
que é muito mais eficiente.
- localização do arquivo:
res/values/filename.xml
O nome do arquivo é arbitrário. Onamedo elemento<plurals>é usado como o ID do recurso.- referência de recurso:
-
Em Kotlin:
R.plurals.plural_name - Sintaxe:
-
<?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:
- exemplo:
Arquivo XML salvo em
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>
Arquivo XML salvo em
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>
Este código do aplicativo extrai uma string plural de dentro de um elemento combinável com
pluralStringResource():@Composable fun SongCount(count: Int) { Text( text = pluralStringResource( R.plurals.numberOfSongsAvailable, count, count, ) ) }
Ao usar a função
pluralStringResource(), você precisa transmitir ocountduas vezes se a string tiver formatação com um número. Por exemplo, para a string%d songs found, o primeiro parâmetrocountseleciona a string plural apropriada, e o segundo parâmetrocounté inserido no marcador%d. Se as strings de plural não tiverem formatação de string, você não vai precisar transmitir o terceiro parâmetro parapluralStringResource.Observação:para recuperar uma string no plural fora de uma função combinável, use
context.resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count).
Formato e estilo
Apresentamos abaixo alguns itens importantes sobre como definir a formatação e o estilo dos seus recursos de string.
Processar caracteres especiais
Quando uma string contém caracteres que têm uso especial em XML, é necessário que eles tenham um escape de acordo com as regras padrão de XML/HTML. Se você precisar de escape para um caractere que tenha um significado especial no Android, use uma barra invertida no início.
Por padrão, o Android procura sequências de caracteres de espaço em branco e as transforma em um único espaço. Para evitar isso, coloque a parte relevante da string entre aspas duplas. Nesse caso, todos os caracteres de espaço em branco (incluindo novas linhas) serão preservados dentro da região entre aspas. Aspas duplas também permitem o uso de aspas simples sem escape comuns.
| Caractere | Formas de escape |
|---|---|
| @ | \@ |
| ? | \? |
| Nova linha | \n |
| Tab | \t |
| Caractere Unicode U+XXXX | \uXXXX |
Aspas simples (') |
Uma destas opções:
|
Aspas duplas (") |
\"
Não é possível inserir a string entre aspas simples. |
A redução dos espaços em branco e o escape de Android acontecem depois que o arquivo de recurso
é analisado como XML. Isso significa que <string>      </string>
(espaço, espaço da pontuação, espaço Unicode Em) são reduzidos em um único espaço
(" "), porque todos são espaços Unicode após a análise do arquivo como um XML.
Para preservar esses espaços como estão, você pode os colocar entre aspas
(<string>"      "</string>)
ou usar o escape do Android
(<string> \u0032 \u8200 \u8195</string>).
Como formatar strings
Se você precisar formatar suas strings, é possível colocar os argumentos de formato no recurso de string, conforme demonstrado no exemplo a seguir.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Este código do aplicativo formata a string de dentro de um elemento combinável transmitindo
argumentos diretamente para stringResource():
@Composable fun WelcomeMessage(username: String, mailCount: Int) { Text( text = stringResource( R.string.welcome_messages, username, mailCount, ) ) }
Aplicar estilo com marcação HTML
Você pode adicionar estilo às suas strings com marcações HTML. Por exemplo:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Os elementos HTML abaixo podem ser usados:
- Negrito:
<b> - Itálico:
<i>,<cite>,<dfn>,<em> - Texto 25% maior:
<big> - Texto 20% menor:
<small> - Definição das propriedades da fonte:
<font face="font_family" color="hex_color">. Exemplos de possíveis famílias de fontes incluemmonospace,serifesans_serif. - Definir uma família de fontes monoespaçadas:
<tt> - Tachado:
<s>,<strike>,<del> - Sublinhado:
<u> - Sobrescrito:
<sup> - Subscrito:
<sub> - Tópicos:
<ul>,<li> - Quebras de linha:
<br> - Divisão:
<div> - Estilo CSS:
<span style="color|background_color|text-decoration"> - Parágrafos:
<p dir="rtl | ltr" style="…">
Em alguns casos, você pode criar um recurso de texto com estilo que também é usado
como uma string de formatação. Normalmente, isso não funciona porque os métodos de formatação,
como stringResource(), tiram todas as informações de estilo da string.
A solução para esse problema é criar tags HTML com entidades com escape, que
são então extraídas com AnnotatedString.fromHtml(), após a realização da formatação. Exemplo:
- Armazene seu recurso de texto com estilo como uma string HTML com escape:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
Nessa string formatada, é adicionado um elemento
<b>. O colchete de abertura tem escape HTML usando a notação<. - Em seguida, formate a string normalmente, mas também chame
AnnotatedString.fromHtml()para converter o texto HTML em uma string estilizada do Compose.
Como fromHtml() formata todas as entidades HTML, não esqueça de usar
TextUtils.htmlEncode() para executar o escape de qualquer caractere HTML possível nas strings usadas com o texto
formatado.
import android.text.TextUtils import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.fromHtml @Composable fun WelcomeHtmlMessage(username: String, mailCount: Int) { // Escape the username in case it contains characters like "<" or "&" val escapedUsername = TextUtils.htmlEncode(username) val text = stringResource( R.string.welcome_messages, escapedUsername, mailCount, ) Text( text = AnnotatedString.fromHtml(text) ) }
Criar um estilo com AnnotatedString
Um AnnotatedString é um objeto de texto do Compose que pode receber estilo com
propriedades como cor e peso da fonte. Crie texto estilizado de forma programática
usando buildAnnotatedString e withStyle.
Este código do aplicativo cria um único elemento do texto com estilos mistos:
@Composable fun StyledGreeting() { val styled = buildAnnotatedString { append("Welcome to ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Android") } append("!") } Text(text = styled) }
Para aplicar cor, tamanho da fonte e decoração de texto, use SpanStyle. Para aplicar
estilos no nível do parágrafo (como alinhamento ou altura da linha), use ParagraphStyle:
@Composable fun RichText() { val text = buildAnnotatedString { withStyle(ParagraphStyle(lineHeight = 24.sp, textAlign = TextAlign.Center)) { withStyle(SpanStyle(color = Color.Gray)) { append("Hello, ") } withStyle( SpanStyle( fontWeight = FontWeight.Bold, color = Color.Red, ) ) { append("world") } append("!") } } Text(text = text) }
Criar o AnnotatedString diretamente é a abordagem recomendada para
apps de um único idioma ou texto estático no Compose. No entanto, para texto estilizado que
exige localização, consulte a abordagem XML <annotation> detalhada na próxima
seção.
Estilizar strings traduzidas com anotações
Para strings que precisam de estilização e tradução personalizadas, defina a tag
<annotation> no strings.xml de cada localidade. Os tradutores preservam a anotação, não importa onde ela esteja na frase. Leia a string com
context.resources.getText(), percorra os intervalos Annotation e converta o
resultado em um AnnotatedString:
@Composable fun AnnotatedTitle() { val context = LocalContext.current val source = context.resources.getText(R.string.title) as SpannedString val text = buildAnnotatedString { append(source.toString()) source.getSpans(0, source.length, Annotation::class.java) .forEach { annotation -> if (annotation.key == "font" && annotation.value == "title_emphasis") { addStyle( SpanStyle( fontFamily = FontFamily( Font(R.font.permanent_marker) ) ), source.getSpanStart(annotation), source.getSpanEnd(annotation), ) } } } Text(text = text) }
A tag <annotation> no seu XML não muda. Apenas o código de recuperação é diferente. Os tradutores ainda movem a tag para envolver a palavra correta em cada
idioma.
Outros recursos
Para mais informações sobre recursos de string, consulte os seguintes recursos adicionais: