Android TextView: “Não concatene o texto exibido com o setText”

136

Estou definindo texto usando setText () da seguinte maneira.

prodNameView.setText("" + name);

prodOriginalPriceView.setText("" + String.format(getString(R.string.string_product_rate_with_ruppe_sign), "" + new BigDecimal(price).setScale(2, RoundingMode.UP)));

Naquele, o primeiro é de uso simples e o segundo é o de definir texto com a formatação do texto.

O Android Studio é muito interessante, usei o Menu Analyze -> Code Cleanupe recebi sugestões acima de duas linhas como.

insira a descrição da imagem aqui

Não concatene o texto exibido com setText. Use a cadeia de recursos com espaços reservados. menos ... (Ctrl + F1)

Ao chamar o TextView # setText:

  • Nunca chame Number # toString () para formatar números; ele não manipulará os separadores de fração e os dígitos específicos da localidade corretamente. Considere usar o formato String # com especificações de formato adequadas (% d ou% f).
  • Não passe uma string literal (por exemplo, "Hello") para exibir o texto. O texto codificado não pode ser traduzido corretamente para outros idiomas. Considere usar seqüências de recursos do Android.
  • Não crie mensagens concatenando pedaços de texto. Essas mensagens não podem ser traduzidas corretamente.

O que posso fazer por isso? Qualquer pessoa pode ajudar a explicar o que é e o que devo fazer?

Pratik Butani
fonte
1
Isso significa que você deve passar apenas um Stringpara dentro setText(). Ex: setText(name)em vez de setText("" + name). Porque se você concatenar o texto, ele não será traduzido como se você usasse o texto codificado como a mensagem notifica
Mr Neo
Mas vai dar NPEse nameforNULL
Pratik Butani
verificação namenão é NULLantes de usar a setText()função.
Neo
2
Você não deve concaturar um recurso String com algum valor; em vez disso, use espaços reservados no seu recurso string. Então, no seu string.xml, você faz: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> E no código java, você faz algo assim: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (você pode fazer a formatação no arquivo xml: [ developer.android.com/guide/topics/resources/…
CodeBreakers

Respostas:

294

O recurso possui a versão sobrecarregada de getString, que leva um varargstipo Object: getString (int, java.lang.Object ...) . Se você configurar corretamente sua string em strings.xml, com os marcadores de posição corretos, poderá usar esta versão para recuperar a versão formatada da sua String final. Por exemplo

<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>

usando getString(R.string.welcome_message, "Test", 0);

android retornará uma String com

 "Hello Test! you have 0 new messages"

Sobre setText("" + name);

Seu primeiro exemplo, prodNameView.setText("" + name);não faz sentido para mim. O TextView é capaz de manipular valores nulos. Se o nome for nulo, nenhum texto será desenhado.

Cinto preto
fonte
1
assumindo que em seu BigDecimal você vai chamar valor float: Adicionar %1$fa sua seqüência, em strings.xml e depois chamarsetText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt
está na segunda parte da resposta. Dê uma olhada
Blackbelt
Eu quero mostrar um inteiro. String significa $ se Decimal $ d. Então inteiro significa?
reegan29
se você quer dizer o "espaço reservado", pode usar %1$d. @ reegan29
Blackbelt
3
Para quem procura a API que lista os tipos de formatos: developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom
34

Não se confunda com % 1 $ s e % 2 $ d na answer.Here aceito é uma informação extra poucos.

  • Os especificadores de formato podem ter a seguinte sintaxe:

% [ argument_index$]format_specifier

  1. O argumento_índice opcional é especificado como um número que termina com um "$" após o "%" e seleciona o argumento especificado na lista de argumentos. O primeiro argumento é referenciado por "1 $" , o segundo por "2 $" etc.
  2. O especificador de formato necessário é um caractere que indica como o argumento deve ser formatado. O conjunto de conversões válidas para um determinado argumento depende do tipo de dados do argumento .

Exemplo

Criaremos a seguinte string formatada onde as partes cinzas são inseridas programaticamente.

Olá Test! você tem 0novas mensagens

O seu string resource:

<string name = "welcome_messages"> Olá %1$s,! Você tem %2$dnovas mensagens </ string>

Faça o string substitutionseguinte:

getString (R.string.welcome_message, "Test", 0);

Nota:

  • % 1 $ s será substituído pela string "Teste"
  • % 2 $ d será substituído pela string "0"
Rissmon Suresh
fonte
16

Encontrei a mesma mensagem de erro de cotão e resolvi-a dessa maneira.

Inicialmente meu código era:

private void displayQuantity(int quantity) {
    TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
    quantityTextView.setText("" + quantity);
}

Eu recebi o seguinte erro

Do not concatenate text displayed with setText. Use resource string with placeholders.

Então, eu adicionei isso ao strings.xml

<string name="blank">%d</string>

Qual é o meu inicial "" + um espaço reservado para o meu número (quantidade).

Nota : Minha quantityvariável foi definida anteriormente e é o que eu queria acrescentar à string. Meu código como resultado foi

private void displayQuantity(int quantity) {
    TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
    quantityTextView.setText(getString(R.string.blank, quantity));
}

Depois disso, meu erro foi embora. O comportamento no aplicativo não mudou e minha quantidade continuou a ser exibida como eu queria agora sem um erro de cotão.

user1580203
fonte
10

Você deve verificar este tópico e usar um espaço reservado como o dele (não testado)

<string name="string_product_rate_with_ruppe_sign">Price : %1$d</string>

String text = String.format(getString(R.string.string_product_rate_with_ruppe_sign),new BigDecimal(price).setScale(2, RoundingMode.UP));
prodOriginalPriceView.setText(text);
ThomasThiebaud
fonte
10

Não concatene o texto dentro do seu método setText () , Concatene o que você quiser em uma String e coloque esse valor String dentro do método setText () .

ex: maneira correta

int min = 120;
int sec = 200;
int hrs = 2;

String minutes = String.format("%02d", mins);
            String seconds = String.format("%02d", secs);
            String newTime = hrs+":"+minutes+":"+seconds;

text.setText(minutes);

Não concatene dentro de setText () como

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
Ashana.Jackol
fonte
Por quê? Que vantagens um tem o outro?
Fureeish 18/03
4

o problema é porque você está anexando ""no início de cada string.

O lint varrerá os argumentos passados setTexte gerará avisos; no seu caso, o seguinte aviso é relevante:

Não crie mensagens concatenando pedaços de texto. Essas mensagens não podem ser traduzidas corretamente.

como você está concatenando cada string com "".

remova essa concatenação, pois os argumentos que você está passando já são texto. Além disso, você pode usar, .toString()se necessário, em qualquer outro lugar, em vez de concatenar sua string com""

Rahul Tiwari
fonte
0

Se você não precisar oferecer suporte ao i18n, poderá desativar esta verificação de cotão no Android Studio

Arquivo -> Configurações -> Editor -> Inspeções -> Android -> Lint -> TextView Internationalization (desmarque esta opção)

ssynhtn
fonte
0

Você pode usar isso, funciona para mim

title.setText(MessageFormat.format("{0} {1}", itemList.get(position).getOppName(), itemList.get(position).getBatchNum()));
bahman karami
fonte
0
prodNameView.setText("" + name); //this produce lint error

val nameStr="" + name;//workaround for quick warning fix require rebuild
prodNameView.setText(nameStr);
SkorpEN
fonte
-1

Não enlouqueça, é muito simples.

String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
            mytextview.setText(result);
mwaqas
fonte