Os apps incluem recursos que podem ser específicos para uma determinada cultura. Por exemplo, um app pode incluir strings próprias de uma cultura que são traduzidas para o idioma da localidade atual. É recomendável manter os recursos específicos da cultura separados do restante do app. O Android resolve recursos específicos de idioma e cultura com base na configuração de localidade do sistema. Você pode oferecer compatibilidade com diferentes localidades usando o diretório de recursos no seu projeto Android.
Você pode especificar recursos adaptados à cultura das pessoas que
usam seu app e fornecer qualquer tipo de recurso
apropriado para o idioma e a cultura dos seus usuários. Por exemplo, a
captura de tela a seguir mostra um app exibindo recursos desenháveis e de string na
localidade padrão do dispositivo (en_US
) e em espanhol
(es_ES
).

Figura 1. Um app que usa recursos diferentes dependendo da localidade atual.
Caso você tenha criado o projeto usando as Ferramentas
do SDK do Android (consulte Criar um
projeto para Android), as ferramentas criarão um diretório res/
no nível superior
do projeto. Dentro desse diretório res/
, há subdiretórios para diversos tipos
de recursos. Há também alguns arquivos padrão, como res/values/strings.xml
, que armazenam
os valores da string.
A compatibilidade com diferentes idiomas vai além do uso de recursos específicos de localidade. Alguns usuários escolhem um idioma que usa scripts da direita para a esquerda (RTL), como árabe ou hebraico, para a localidade da IU. Outros usuários visualizam ou geram conteúdo em um idioma que usa scripts RTL, mesmo que tenham definido um idioma que usa scripts da esquerda para a direita (LTR), como o inglês, como a localidade da IU. Para ser compatível com os dois tipos de usuários, seu app precisa fazer o seguinte:
- Empregar um layout de IU RTL para localidades RTL.
- Detectar e declarar a direção dos dados de texto que são exibidos em mensagens formatadas. Normalmente, basta chamar um método que determine a direção dos dados de texto para você.
Criar diretórios de localidade e arquivos de recursos
Para aumentar a compatibilidade com mais localidades, crie mais diretórios dentro de
res/
. O nome de cada diretório precisa seguir este formato:
<resource type>-b+<language code>[+<country code>]
Por exemplo, values-b+es/
contém recursos
de string para localidades com o código de idioma es
. Da mesma forma,
mipmap-b+es+ES/
contém ícones para localidades com o código do idioma es
e o código do país ES
.
O Android carrega os recursos apropriados de acordo com as configurações de localidade do
dispositivo no momento da execução. Para mais informações, consulte
Como fornecer recursos alternativos.
Depois de decidir para quais localidades seu app oferecerá compatibilidade, crie os subdiretórios e arquivos de recursos. Exemplo:
MyProject/ res/ values/ strings.xml values-b+es/ strings.xml mipmap/ country_flag.png mipmap-b+es+ES/ country_flag.png
Por exemplo, a seguir estão diferentes arquivos de recursos para diversos idiomas:
Strings em inglês (localidade padrão), /values/strings.xml
:
<resources> <string name="hello_world">Hello World!</string> </resources>
Strings em espanhol (localidade es
), /values-es/strings.xml
:
<resources> <string name="hello_world">¡Hola Mundo!</string> </resources>
Ícone da bandeira dos Estados Unidos (localidade padrão),
/mipmap/country_flag.png
:

Figura 2. Ícone usado para a localidade padrão (en_US).
Ícone da bandeira da Espanha (localidade es_ES
),
/mipmap-b+es+ES/country_flag.png
:

Figura 3. Ícone usado para a localidade es_ES
.
Observação: é possível usar o qualificador de localidade (ou qualquer qualificador de configuração) em qualquer tipo de recurso. Por exemplo, você pode fornecer versões localizadas do seu drawable de bitmap. Para mais informações, consulte Localização.
Usar os recursos no seu app
Você pode referenciar os recursos no seu código-fonte e em outros arquivos XML usando
o atributo name
de cada recurso.
No código-fonte, é possível referenciar um recurso de string com a sintaxe
R.<resource type>.<resource name>
. Há diversos
métodos que aceitam um recurso dessa maneira.
Exemplo:
Kotlin
// Get a string resource from your app's Resources val hello = resources.getString(R.string.hello_world) // Or supply a string resource to a method that requires a string TextView(this).apply { setText(R.string.hello_world) }
Java
// Get a string resource from your app's Resources String hello = getResources().getString(R.string.hello_world); // Or supply a string resource to a method that requires a string TextView textView = new TextView(this); textView.setText(R.string.hello_world);
Em outros arquivos XML, você poderá referenciar um recurso de string com a sintaxe
@<resource type>/<resource name>
sempre que o atributo XML aceitar um valor compatível.
Exemplo:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/country_flag" />
Importante: para que as configurações de idioma do usuário sejam priorizadas
corretamente, especifique os idiomas que têm suporte no app usando a propriedade resConfigs
. Para
mais informações, consulte
Especificar os idiomas com suporte no app.
Formatar texto em mensagens
Uma das tarefas mais comuns em um app é a formatação de texto. As mensagens localizadas são formatadas ao inserir texto e dados numéricos nas posições apropriadas. Ao lidar com uma IU ou com dados RTL, a formatação simples pode exibir textos incorretos ou mesmo ilegíveis.
Em geral, idiomas como árabe, hebraico, persa e urdu são escritos na direção RTL. No entanto, alguns dos elementos, como números e texto LTR incorporados, são escritos na direção LTR dentro do texto RTL. Os idiomas que usam scripts LTR, incluindo o inglês, também são bidirecionais, porque podem conter scripts RTL incorporados que precisariam ser exibidos na direção RTL.
Na maioria das vezes, são os próprios apps que geram essas instâncias de texto de direção oposta incorporadas. Eles inserem dados de texto de um idioma arbitrário — e uma direção de texto arbitrária — em mensagens localizadas. Essa mistura de direções não costuma incluir uma indicação clara de onde o texto em direção oposta começa e termina. Essas características do texto gerado pelo app causam a maior parte dos problemas.
Embora o tratamento padrão do sistema de texto bidirecional normalmente renderize o texto conforme o esperado, é possível que ele não seja renderizado corretamente quando o app o inserir em uma mensagem localizada. As seguintes situações apresentam exemplos de casos em que há uma grande probabilidade de que o texto não apareça corretamente:
-
Inserido no começo da mensagem:
PERSON_NAME está ligando para você
-
Começa com um número, como em endereços ou números de telefone:
987 654-3210
-
Começa com pontuação, como em um número de telefone:
+19876543210
-
Termina com pontuação:
Tem certeza?
-
Já tem as duas direções:
A palavra בננה significa banana em hebraico.
Exemplo
Por exemplo, suponha que um app às vezes precise exibir a mensagem “Você quis dizer %s?”, com um endereço inserido no lugar de “%s” no momento da execução. Como o app é compatível com IUs para localidades diferentes, a mensagem é proveniente de um recurso específico de localidade e usa a direção RTL quando uma localidade RTL está em uso. Para uma IU em hebraico, a mensagem seria exibida assim:
האם התכוונת ל %s?
No entanto, a sugestão pode vir de um banco de dados que não inclui texto no idioma da localidade. Por exemplo, se o endereço em questão for de um lugar na Califórnia, ele aparecerá no banco de dados com texto em inglês. Se você inserir o endereço "15 Bay Street, Laurel, CA" na mensagem RTL sem fornecer quaisquer dicas sobre a direção do texto, o resultado não será o esperado nem correto:
האם התכוונת ל 15 Bay Street, Laurel, CA?
Veja que o número da casa aparece à direita do endereço, e não à esquerda, como seria esperado. Isso faz com que o número pareça um código postal estranho. O mesmo problema pode ocorrer se você incluir texto RTL em uma mensagem que usa a direção de texto LTR.
Explicação e solução
O problema do exemplo anterior ocorre porque o formatador de texto não especifica que "15" faz parte do endereço. Por isso, o sistema não pode determinar se "15" faz parte do texto RTL que vem antes dele ou do texto LTR que vem depois.
Para resolver esse problema, use o método unicodeWrap()
, encontrado na classe BidiFormatter
, em
todas as partes do texto que você inserir em mensagens localizadas.
Estas são as únicas situações em que não é recomendável
usar
unicodeWrap()
:
- O texto está inserido em uma string legível por máquina, como uma consulta de URI ou SQL.
- Você já sabe que a formatação do texto está correta.
O método unicodeWrap()
detecta a direção de uma string e une-a em caracteres de formatação Unicode
que declaram essa direção. Como o "15" agora está dentro do texto
declarado como LTR, ele será exibido na posição correta:
האם התכוונת ל 15 Bay Street, Laurel, CA?
O snippet de código a seguir demonstra como usar
unicodeWrap()
:
Kotlin
val mySuggestion = "15 Bay Street, Laurel, CA" val myBidiFormatter: BidiFormatter = BidiFormatter.getInstance() // The "did_you_mean" localized string resource includes // a "%s" placeholder for the suggestion. String.format(getString(R.string.did_you_mean), myBidiFormatter.unicodeWrap(mySuggestion))
Java
String mySuggestion = "15 Bay Street, Laurel, CA"; BidiFormatter myBidiFormatter = BidiFormatter.getInstance(); // The "did_you_mean" localized string resource includes // a "%s" placeholder for the suggestion. String.format(getString(R.string.did_you_mean), myBidiFormatter.unicodeWrap(mySuggestion));
Observação: caso seu app seja destinado ao Android 4.3 (nível 18 da API) ou
mais recente, use a versão do BidiFormatter
disponível no
framework do Android. Caso contrário, use a versão do
BidiFormatter
disponível na Biblioteca de Suporte.
Formatar números
Use strings de formato, e não chamadas de método, para converter números em strings na lógica do app:
Kotlin
var myIntAsString = "$myInt"
Java
String myIntAsString = String.format("%d", myInt);
Isso formatará os números corretamente para sua localidade, o que pode incluir o uso de um conjunto diferente de dígitos.
Ao usar
String.format()
para criar uma
consulta SQL em um dispositivo com uma localidade que usa o próprio conjunto de dígitos, como persa
e a maioria das localidades em árabe, poderá haver problemas se os parâmetros da consulta
forem números. Isso acontece porque o número é formatado nos dígitos da localidade, que
são inválidos em SQL.
Para preservar números formatados em ASCII e manter a consulta SQL válida, use
a versão sobrecarregada de
String.format()
, que
inclui uma localidade como primeiro parâmetro. O argumento da localidade precisa ser
Locale.US
.
Compatibilidade com o espelhamento de layout
As pessoas que usam scripts RTL preferem uma interface de usuário RTL, o que inclui menus e textos alinhados à direita, além de setas de encaminhamento apontando para a esquerda.
A Figura 4 mostra o contraste entre a versão LTR de uma tela do app Configurações e a versão RTL equivalente:


Ao adicionar suporte para RTL ao app, é especialmente importante lembrar que:
- O espelhamento de texto RTL só é compatível com apps quando usado em dispositivos com o Android 4.2 (nível 17 da API) ou mais recente. Para aprender a oferecer suporte ao espelhamento de texto em dispositivos mais antigos, consulte Oferecer suporte a apps legados.
- Para testar se o app é compatível com a direção de texto RTL, use as opções do desenvolvedor para testá-lo e convide pessoas que usam scripts RTL para usar o app.
Observação: para ver outras diretrizes de design relacionadas ao espelhamento de layout, incluindo uma lista de elementos que você precisa ou não espelhar, consulte as diretrizes do Material Design para Bidirecionalidade (link em inglês).
Ao espelhar o layout da IU no seu app para que ele seja exibido como RTL em uma localidade RTL, conclua as etapas das seções a seguir.
Modificar os arquivos de versão e manifesto
Modifique o arquivo build.gradle
do módulo do app e o arquivo de manifesto
da seguinte maneira:
build.gradle (Module: app)
Groovy
android { ... defaultConfig { targetSdkVersion 17 // Or higher ... } }
Kotlin
android { ... defaultConfig { targetSdkVersion(17) // Or higher ... } }
AndroidManifest.xml
<manifest ... > ... <application ... android:supportsRtl="true"> </application> </manifest>
Observação: caso seu app seja destinado ao Android 4.1.1 (nível 16 da API) ou
anterior, o atributo android:supportsRtl
será ignorado, junto dos valores
start
e end
que aparecem nos
arquivos de layout do app. Nesse caso, o espelhamento de layout RTL não acontecerá
automaticamente no app.
Atualizar os recursos existentes
Converta left
e right
para start
e
end
, respectivamente, em cada um dos arquivos de recursos de layout existentes.
Ao fazer isso, você permite que o framework alinhe os elementos da IU do app com base
nas configurações de idioma do usuário.
Observação: antes de atualizar seus recursos, aprenda a oferecer compatibilidade com apps legados ou apps destinados ao Android 4.1.1 (nível 16 da API) e versões anteriores.
Para usar os recursos de alinhamento RTL do framework, altere os atributos nos seus arquivos de layout que aparecem na Tabela 1.
Tabela 1. Atributos que serão usados quando seu app for compatível com várias direções de texto.
A Tabela 2 mostra como o sistema processa os atributos de alinhamento da IU com base na
versão do SDK de destino, estejam os atributos left
e right
,
bem como os atributos start
e end
,
definidos ou não.
Tabela 2. Comportamento de alinhamento do elemento da IU com base na versão do SDK de destino e nos atributos definidos.
|
Esquerda e direita definidas? | Início e término definidos? | Resultado |
---|---|---|---|
Sim | Sim | Sim |
start e end resolvidos e sobreposição de
left e right
|
Sim | Sim | Não | Somente left e right são usados |
Sim | Não | Sim | Somente start e end são usados |
Não | Sim | Sim |
left e right são usados (start e
end são ignorados)
|
Não | Sim | Não | Somente left e right são usados |
Não | Não | Sim |
start e end resolvidos para left e
right
|
Adicionar recursos específicos de direção e idioma
Nesta etapa, serão adicionadas versões específicas dos seus arquivos de recursos de valor, layout e drawables que contém valores personalizados para diferentes idiomas e direções de texto.
No Android 4.2 (nível 17 da API) ou mais recente, você pode usar os qualificadores de recurso -ldrtl
(layout da direita para a esquerda) e -ldltr
(layout da esquerda para a direita). Para manter a compatibilidade
com versões anteriores do carregamento de recursos existentes, as versões mais antigas do Android usam os
qualificadores de idioma de um recurso para inferir a direção correta do texto.
Suponha que você queira adicionar um arquivo de layout específico para ser compatível com scripts RTL,
como os idiomas hebraico, árabe e persa. Para fazer isso, adicione um diretório
layout-ldrtl/
ao diretório res/
, conforme
mostrado no seguinte exemplo:
res/ layout/ main.xml This layout file is loaded by default. layout-ldrtl/ main.xml This layout file is loaded for languages using an RTL text direction, including Arabic, Persian, and Hebrew.
Se você quiser adicionar uma versão específica do layout criada apenas para texto em árabe, a estrutura do diretório será a seguinte:
res/ layout/ main.xml This layout file is loaded by default. layout-ar/ main.xml This layout file is loaded for Arabic text. layout-ldrtl/ main.xml This layout file is loaded only for non-Arabic languages that use an RTL text direction.
Observação: os recursos específicos de idioma têm precedência sobre os recursos específicos de direção do layout, que têm precedência sobre os recursos padrão.
Usar widgets compatíveis
A partir do Android 4.2 (nível 17 da API), a maior parte dos elementos da IU do framework é automaticamente compatível
com a direção de texto RTL. No entanto, vários elementos do framework, como
ViewPager
, não são compatíveis com a direção
de texto RTL.
Os widgets da tela inicial são compatíveis com a direção do texto RTL, desde que os
arquivos de manifesto correspondentes incluam a atribuição do atributo
android:supportsRtl="true"
.
Oferecer compatibilidade com apps legados
Caso seu app seja direcionado ao Android 4.1.1 (nível 16 da API) ou versões mais recentes, inclua também os atributos
left
e right
, além de
start
e end
.
Para verificar se o layout precisa usar a direção de texto RTL, use a seguinte lógica:
Kotlin
private fun shouldUseLayoutRtl(): Boolean { return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { View.LAYOUT_DIRECTION_RTL == layoutDirection } else { false } }
Java
private boolean shouldUseLayoutRtl() { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { return View.LAYOUT_DIRECTION_RTL == getLayoutDirection(); } else { return false; } }
Observação: para evitar problemas de compatibilidade, use a versão 23.0.1 ou mais recente das Ferramentas de build do SDK do Android.
Testar o uso de opções do desenvolvedor
Em dispositivos com o Android 4.4 (nível 19 da API) ou versões mais recentes, é possível ativar a configuração Forçar layout da direita p/ esquerda nas Opções do desenvolvedor no dispositivo. Com essa configuração, você pode ver o texto que usa scripts LTR, como texto em inglês, no modo RTL.
Atualizar a lógica do app
Esta seção descreve locais específicos que precisam ser atualizados na lógica do seu app ao adaptá-lo para processar várias direções de texto.
Alterações de propriedade
Para gerenciar uma mudança em qualquer propriedade relacionada a RTL, como direção
e parâmetros de layout, preenchimento, direção e alinhamento de texto ou
posicionamento de drawables, use o
callback
onRtlPropertiesChanged()
. Esse callback permite ver a direção atual do layout e
atualizar os objetos View
de uma atividade corretamente.
Visualizações
Se você estiver criando um widget de IU que não faça parte diretamente da hierarquia de visualização de uma atividade, como uma caixa de diálogo ou um elemento semelhante a um aviso, defina a direção correta do layout com base no contexto. O snippet de código a seguir demonstra como concluir esse processo:
Kotlin
val config: Configuration = context.resources.configuration view.layoutDirection = config.layoutDirection
Java
final Configuration config = getContext().getResources().getConfiguration(); view.setLayoutDirection(config.getLayoutDirection());
Vários métodos da classe View
precisam de
considerações adicionais:
onMeasure()
- As medidas de visualização podem variar, dependendo da direção do texto.
onLayout()
- Se criar o próprio layout de implementação, você precisará chamar
super()
na sua versão deonLayout()
e adaptar a lógica personalizada para que ela seja compatível com scripts RTL. onDraw()
- Se você estiver implementando uma visualização personalizada ou adicionando uma funcionalidade avançada a um
desenho, atualize seu código para oferecer compatibilidade com scripts RTL. Use o
seguinte código para determinar se o widget está no modo RTL:
Kotlin
// On devices running Android 4.1.1 (API level 16) and lower, // you can call the isLayoutRtl() system method directly. fun isLayoutRtl(): Boolean = layoutDirection == LAYOUT_DIRECTION_RTL
Java
// On devices running Android 4.1.1 (API level 16) and lower, // you can call the isLayoutRtl() system method directly. public boolean isLayoutRtl() { return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); }
Drawables
Se você tiver um drawable que precise ser espelhado para um layout de RTL, conclua uma destas etapas com base na versão de Android do dispositivo:
-
Em dispositivos com o Android 4.3 (nível 18 da API) e versões anteriores, você precisa
adicionar e definir arquivos de recurso
-ldrtl
. -
No Android 4.4 (nível 19 da API) e versões mais recentes, você pode usar
android:autoMirrored="true"
ao definir seu drawable, o que permite ao sistema processar o espelhamento de layout RTL.Observação: o atributo
android:autoMirrored
funciona apenas para drawables simples, em que o espelhamento bidirecional é simplesmente um espelhamento gráfico do drawable como um todo. Caso o drawable contenha vários elementos ou se refleti-lo mudaria a interpretação dele, faça o espelhamento manualmente. Sempre que possível, verifique com um especialista em bidirecionamento se os drawables espelhados fazem sentido para os usuários.
Gravidade
Se o código do seu app estiver usando Gravity.LEFT
ou
Gravity.RIGHT
, você precisará alterar
esses valores para Gravity.START
e
Gravity.END
, respectivamente.
Por exemplo, se você estiver usando o seguinte código:
Kotlin
when (gravity and Gravity.HORIZONTAL_GRAVITY_MASK) { Gravity.LEFT -> { // Handle objects that are left-aligned. } Gravity.RIGHT -> { // Handle objects that are right-aligned. } }
Java
switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: // Handle objects that are left-aligned. break; case Gravity.RIGHT: // Handle objects that are right-aligned. break; }
… vai precisar mudá-lo para:
Kotlin
val absoluteGravity: Int = Gravity.getAbsoluteGravity(gravity, layoutDirection) when (absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK) { Gravity.LEFT -> { // Handle objects that are left-aligned. } Gravity.RIGHT -> { // Handle objects that are right-aligned. } }
Java
final int layoutDirection = getLayoutDirection(); final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection); switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.LEFT: // Handle objects that are left-aligned. break; case Gravity.RIGHT: // Handle objects that are right-aligned. break; }
Isso significa que você pode manter seu código existente que processa valores alinhados à esquerda e
à direita, mesmo que esteja usando start
e
end
para seus valores de gravidade.
Observação: ao aplicar as configurações de gravidade, use uma
versão sobrecarregada de Gravity.apply()
que inclua um argumento
layoutDirection
.
Margem e padding
Para oferecer compatibilidade com scripts RTL no app, siga estas práticas recomendadas relacionadas aos valores de margem e de preenchimento:
-
Use
getMarginStart()
egetMarginEnd()
em vez dos equivalentes do atributo específico da direção,leftMargin
erightMargin
. -
Ao usar
setMargins()
, troque os valores dos argumentosleft
eright
se o app detectar scripts RTL. -
Se o app inclui lógica de preenchimento personalizada, substitua
setPadding()
esetPaddingRelative()
.
Suporte à seleção de idioma por app
Em muitos casos, os usuários multilíngues definem um idioma para o sistema, como o inglês, mas querem selecionar outros para apps específicos, como holandês, chinês ou hindi. Para que os apps possam oferecer uma experiência melhor a esses usuários, o Android 13 inclui os recursos abaixo para apps que têm suporte a vários idiomas:
-
Configurações do sistema: um local centralizado em que os usuários podem selecionar um idioma preferido para cada app.
O app precisa declarar o atributo
android:localeConfig
no manifesto para informar ao sistema que ele tem suporte a vários idiomas. Para saber mais, consulte as instruções sobre como criar e declarar um arquivo de recursos no manifesto do app. -
Outras APIs: essas APIs públicas, como os métodos
setApplicationLocales()
egetApplicationLocales()
na classeLocaleManager
, permitem que os apps definam um idioma diferente daquele usado pelo sistema durante a execução.Apps que usam seletores de idioma personalizados precisam utilizar essas novas APIs para garantir que os usuários tenham uma experiência consistente, não importa onde selecionem as preferências de idioma. As APIs públicas também ajudam a reduzir a quantidade de código boilerplate e oferecem suporte para APKs divididos e Backup automático , permitindo que os apps armazenem as seleções de idioma do usuário.
Para oferecer compatibilidade com versões anteriores do Android, APIs equivalentes também estão disponíveis no AndroidX. Recomendamos o uso da Appcompat 1.6.0-beta01 ou versões mais recentes.
Para saber mais, consulte as instruções de como implementar as novas APIs.
Veja também
Outros recursos
Para saber mais sobre como oferecer compatibilidade com dispositivos mais antigos, acesse os seguintes recursos: