É possível ter espaços reservados em valores de seqüência string.xml
que possam ser atribuídos a valores em tempo de execução?
Exemplo:
alguma string PLACEHOLDER1 um pouco mais de string
É possível ter espaços reservados em valores de seqüência string.xml
que possam ser atribuídos a valores em tempo de execução?
Exemplo:
alguma string PLACEHOLDER1 um pouco mais de string
Respostas:
Sim, consulte o seguinte em Recursos da cadeia de caracteres: Formatação e estilo
Se você precisar formatar suas strings usando
String.format(String, Object...)
, poderá fazê-lo colocando seus argumentos de formato no recurso de strings. Por exemplo, com o seguinte recurso:<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Neste exemplo, a string de formato possui dois argumentos:
%1$s
é uma string e%2$d
é um número decimal. Você pode formatar a string com argumentos do seu aplicativo, como este:Resources res = getResources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
Observe que getString
há uma sobrecarga que usa a string como uma string de formato:
String text = res.getString(R.string.welcome_messages, username, mailCount);
Se você precisar lidar com plurais, use o seguinte:
<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>
O primeiro mailCount
parâmetro é usado para decidir qual formato usar (único ou plural); os outros parâmetros são suas substituições:
Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);
Consulte Recursos de seqüência de caracteres: Plurais para obter mais detalhes.
Quando vi pela primeira vez %1$s
e %2$d
na resposta aceita, não fazia sentido. Aqui está um pouco mais de explicação.
Eles são chamados de especificadores de formato. Na sequência xml, eles estão na forma de
%[parameter_index$][format_type]
1$
, 2$
e 3$
. A ordem em que você as coloca na cadeia de recursos não importa, apenas a ordem em que você fornece os parâmetros.tipo de formato : existem várias maneiras de formatar as coisas ( consulte a documentação ). Aqui estão alguns comuns:
s
cordad
número inteiro decimalf
número de ponto flutuanteCriaremos a seguinte string formatada em que as partes cinzas são inseridas programaticamente.
Minha irmã
Mary
tem12
anos.
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 estava em uma atividade. Você pode usar context.getResources().getString(...)
se não estiver disponível.String.format()
também formatará uma String.1$
e 2$
não precisam ser usados nessa ordem. Ou seja, 2$
pode vir antes 1$
. Isso é útil ao internacionalizar um aplicativo para idiomas que usam uma ordem de palavras diferente.%1$s
várias vezes no xml, se desejar repeti-lo.%%
para obter o %
personagem real .Quando você deseja usar um parâmetro do arquivo strings.xml real sem usar nenhum 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>
Isso não funciona nos arquivos de recursos, ou seja, as variáveis devem ser copiadas em cada arquivo XML que precisa delas.
<!DOCTYPE... ]>
peça em um arquivo separado e incluí-la em vários arquivos de recursos? Algum truque para conseguir isso?
Estava procurando o mesmo e finalmente encontrou a seguinte solução muito simples. Melhor: funciona imediatamente.
1. altere seu recurso de string:
<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. use substituição de string:
c.getString(R.string.welcome_messages,name,count);
onde c é o contexto, name é uma variável de string e conta sua variável int
Você precisará incluir
<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">
em seu res / strings.xml. Funciona para mim. :)
xliff
tags nos especificadores de formato? Que valor extra eles agregam em vez de usar os especificadores %s
e %d
por conta própria?
No Kotlin, você só precisa definir o valor da string assim:
<string name="song_number_and_title">"%1$d ~ %2$s"</string>
Crie uma exibição de texto no seu layout:
<TextView android:id="@+id/song_number_and_title"/>
Em seguida, faça isso no seu código se você estiver usando o 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))
Pode ser necessário obter seus recursos no contexto do aplicativo.
No entanto, você também deve ler a resposta de Elias Mårtenson no plural de Android, tratamento de "zero" . Há um problema com a interpretação de certos valores, como "zero".
em res / values / string.xml
<resources>
<string name="app_name">Hello World</string>
<string name="my_application">Application name: %s, package name: %s</string>
</resources>
no 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);
Você pode usar MessageFormat
:
<string name="customer_address">Wellcome: {0} {1}</string>
No código Java:
String text = MessageFormat(R.string.customer_address).format("Name","Family");
API nível 1:
https://developer.android.com/reference/java/text/MessageFormat.html
Se você deseja escrever por cento (%), duplique-o:
<string name="percent">%1$d%%</string>
label.text = getString(R.string.percent, 75) // Output: 75%.
Se você escrever simplesmente %1$d%
, você receberá o erro: Format string 'percent' is not a valid format string so it should not be passed to String.format
.
Sim! você pode fazer isso sem escrever nenhum código Java / Kotlin, apenas XML, usando esta pequena biblioteca que eu criei, que faz isso no momento da construção, para que seu aplicativo não seja afetado por ele: https://github.com/LikeTheSalad/android -string-reference
Uso
Suas cordas:
<resources>
<string name="app_name">My App Name</string>
<string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>
A sequência gerada após a construção:
<!--resolved.xml-->
<resources>
<string name="welcome_message">Welcome to My App Name</string>
</resources>
Uma solução direta da Kotlin para o 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 )
No seu arquivo de string, use este
<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>
E no seu código, use da mesma maneira
coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
, rewardPoints.getConversion_rate(), getString(R.string.rs)));
Versão Kotlin da resposta aceita ...
val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
resources.getString(int, ... args)
método com argumentos em vez de String.format
. Também não há detalhes específicos do kotlin neste código, além da val
palavra - chave. Veja a resposta de msbodw001