Android TextView: "Ne pas concaténer le texte affiché avec setText"

136

Je mets du texte en utilisant setText () de la manière suivante.

prodNameView.setText("" + name);

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

Dans ce premier est une utilisation simple et le deuxième est la mise en forme du texte avec le texte de mise en forme.

Android Studio est tellement intéressant, j'ai utilisé Menu Analyze -> Code Cleanupet j'ai reçu des suggestions sur deux lignes comme.

entrez la description de l'image ici

Ne concaténez pas le texte affiché avec setText. Utilisez une chaîne de ressource avec des espaces réservés. moins ... (Ctrl + F1)

Lors de l'appel de TextView # setText:

  • N'appelez jamais Number # toString () pour formater les nombres; il ne gérera pas correctement les séparateurs de fractions et les chiffres spécifiques aux paramètres régionaux. Pensez à utiliser le format String # avec des spécifications de format appropriées (% d ou% f) à la place.
  • Ne transmettez pas de chaîne littérale (par exemple "Hello") pour afficher le texte. Le texte codé en dur ne peut pas être correctement traduit dans d'autres langues. Envisagez plutôt d'utiliser des chaînes de ressources Android.
  • Ne créez pas de messages en concaténant des blocs de texte. Ces messages ne peuvent pas être correctement traduits.

Que puis-je faire pour cela? N'importe qui peut aider à expliquer ce qu'est la chose et que dois-je faire?

Pratik Butani
la source
1
Cela signifie que vous ne devez passer qu'un Stringdans setText(). Ex: setText(name)au lieu de setText("" + name). Parce que si vous concaténez du texte, il ne sera pas traduit comme vous utilisez le texte codé en dur comme notification de message
M. Neo
Mais ça donnera NPEsi namec'estNULL
Pratik Butani
vérifier namen'est pas NULLavant d'utiliser la setText()fonction.
Mr Neo
2
Vous ne devez pas concater une ressource String avec une valeur, utilisez plutôt des espaces réservés dans votre ressource chaîne. Donc, dans votre string.xml, vous faites: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> Et dans votre code java, vous faites quelque chose comme ceci: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (vous pouvez faire le formatage dans le fichier xml: [ developer.android.com/guide/topics/resources/…
CodeBreakers

Réponses:

294

La ressource a la version surchargée de getString qui prend un varargsde type Object: getString (int, java.lang.Object ...) . Si vous configurez correctement votre chaîne dans strings.xml, avec les espaces réservés appropriés, vous pouvez utiliser cette version pour récupérer la version formatée de votre chaîne finale. Par exemple

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

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

android renverra une chaîne avec

 "Hello Test! you have 0 new messages"

À propos setText("" + name);

Votre premier exemple prodNameView.setText("" + name);n'a aucun sens pour moi. Le TextView est capable de gérer des valeurs nulles. Si le nom est nul, aucun texte ne sera dessiné.

Ceinture noire
la source
1
en supposant que sur votre BigDecimal, vous appellerez la valeur flottante: Ajoutez %1$fà votre chaîne, dans strings.xml, puis appelezsetText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt
c'est dans la deuxième partie de la réponse. Jetez un oeil
Blackbelt
Je veux montrer un Integer .String représente $ s et Decimal $ d. Donc, entier signifie?
reegan29
si vous voulez dire "l'espace réservé" que vous pouvez utiliser %1$d. @ reegan29
Blackbelt
3
Pour tous ceux qui recherchent l'API répertoriant les types de formats: developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom
34

Ne vous méprenez pas avec % 1 $ s et % 2 $ d dans la réponse acceptée, voici quelques informations supplémentaires.

  • Les spécificateurs de format peuvent avoir la syntaxe suivante:

% [ argument_index$]format_specifier

  1. L' argument_index facultatif est spécifié sous la forme d'un nombre se terminant par un «$» après le «%» et sélectionne l'argument spécifié dans la liste d'arguments. Le premier argument est référencé par "1 $" , le second par "2 $" , etc.
  2. Le spécificateur de format requis est un caractère indiquant comment l'argument doit être formaté. L'ensemble des conversions valides pour un argument donné dépend du type de données de l'argument .

Exemple

Nous allons créer la chaîne formatée suivante où les parties grises sont insérées par programme.

Bonjour Test! vous avez de 0nouveaux messages

Votre string resource:

<String name = "welcome_messages"> Bonjour, %1$s! Vous avez de %2$dnouveaux messages </ string>

Procédez string substitutioncomme indiqué ci-dessous:

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

Remarque:

  • % 1 $ s sera remplacé par la chaîne "Test"
  • % 2 $ d sera remplacé par la chaîne "0"
Rissmon Suresh
la source
16

J'ai rencontré le même message d'erreur de peluches et je l'ai résolu de cette façon.

Au départ, mon code était:

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

J'ai eu l'erreur suivante

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

Alors, j'ai ajouté ceci à strings.xml

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

Quel est mon "" initial + un espace réservé pour mon numéro (quantité).

Remarque : Ma quantityvariable a été précédemment définie et c'est ce que je voulais ajouter à la chaîne. Mon code en conséquence était

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

Après cela, mon erreur a disparu. Le comportement de l'application n'a pas changé et ma quantité a continué à s'afficher comme je le voulais maintenant sans erreur de peluche.

user1580203
la source
10

Vous devriez vérifier ce fil et utiliser un espace réservé comme le sien (non testé)

<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
la source
10

Ne concaténez pas de texte dans votre méthode setText () , concaténez ce que vous voulez dans un String et mettez cette valeur String dans votre méthode setText () .

ex: manière correcte

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);

Ne pas concaténer à l'intérieur de setText () comme

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
Ashana.Jackol
la source
Pourquoi? Quels avantages l'un a-t-il l'autre?
Fureeish
4

le problème est que vous ajoutez ""au début de chaque chaîne.

lint analysera les arguments passés à setTextet générera des avertissements, dans votre cas, l'avertissement suivant est pertinent:

Ne créez pas de messages en concaténant des blocs de texte. Ces messages ne peuvent pas être correctement traduits.

comme vous concaténez chaque chaîne avec "".

supprimez cette concaténation car les arguments que vous passez sont déjà du texte. En outre, vous pouvez utiliser .toString()si nécessaire n'importe où ailleurs au lieu de concaténer votre chaîne avec""

Rahul Tiwari
la source
0

Si vous n'avez pas besoin de prendre en charge i18n, vous pouvez désactiver cette vérification des peluches dans Android Studio

Fichier -> Paramètres -> Editeur -> Inspections -> Android -> Lint -> TextView Internationalization (décochez ceci)

ssynhtn
la source
0

Tu peux utiliser ça, ça marche pour moi

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

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

Ne soyez pas fou, c'est trop simple.

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