Android TextView: "Mit setText angezeigten Text nicht verketten"

136

Ich setze Text mit setText () wie folgt.

prodNameView.setText("" + name);

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

In diesem ersten Fall ist die Verwendung einfach und im zweiten Fall wird Text mit Formatierungstext festgelegt.

Android Studio ist so sehr interessant, ich habe Menü verwendet Analyze -> Code Cleanupund ich habe Vorschläge über zwei Zeilen wie bekommen.

Geben Sie hier die Bildbeschreibung ein

Verketten Sie den mit setText angezeigten Text nicht. Verwenden Sie eine Ressourcenzeichenfolge mit Platzhaltern. weniger ... (Strg + F1)

Beim Aufrufen von TextView # setText:

  • Rufen Sie niemals Number # toString () auf, um Nummern zu formatieren. Bruchtrennzeichen und länderspezifische Ziffern werden nicht richtig behandelt. Verwenden Sie stattdessen das String # -Format mit den richtigen Formatspezifikationen (% d oder% f).
  • Übergeben Sie kein Zeichenfolgenliteral (z. B. "Hallo"), um Text anzuzeigen. Hardcodierter Text kann nicht richtig in andere Sprachen übersetzt werden. Verwenden Sie stattdessen Android-Ressourcenzeichenfolgen.
  • Erstellen Sie keine Nachrichten, indem Sie Textblöcke verketten. Solche Nachrichten können nicht richtig übersetzt werden.

Was kann ich dafür tun? Jeder kann helfen zu erklären, was die Sache ist und was ich tun soll?

Pratik Butani
quelle
1
Das heißt, Sie sollten nur ein Stringin übergeben setText(). Bsp.: setText(name)Anstelle von setText("" + name). Denn wenn Sie Text verketten, wird er nicht so übersetzt, als würden Sie fest codierten Text als Benachrichtigung für die Nachricht verwenden
Mr Neo
Aber es wird geben, NPEwenn es nameistNULL
Pratik Butani
Überprüfung nameist nicht NULLvor Verwendung der setText()Funktion.
Herr Neo
2
Sie sollten eine String-Ressource nicht mit einem bestimmten Wert verknüpfen, sondern Platzhalter in Ihrer String-Ressource verwenden. In Ihrer string.xml tun Sie Folgendes: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> Und in Ihrem Java-Code tun Sie Folgendes : prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (Sie können die Formatierung in der XML-Datei
vornehmen

Antworten:

294

Ressource hat die get überladene Version von getString , die eine nimmt varargsvom Typ Object: getString (int, java.lang.Object ...) . Wenn Sie Ihre Zeichenfolge in strings.xml mit den richtigen Platzhaltern korrekt eingerichtet haben, können Sie diese Version verwenden, um die formatierte Version Ihrer endgültigen Zeichenfolge abzurufen. Z.B

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

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

android gibt einen String mit zurück

 "Hello Test! you have 0 new messages"

Über setText("" + name);

Ihr erstes Beispiel prodNameView.setText("" + name);ergibt für mich keinen Sinn. Die Textansicht kann Nullwerte verarbeiten. Wenn der Name null ist, wird kein Text gezeichnet.

Schwarzer Gürtel
quelle
1
Angenommen, Sie rufen auf Ihrem BigDecimal den Gleitkommawert auf: Fügen Sie ihn %1$fzu Ihrer Zeichenfolge in strings.xml hinzu und rufen Sie dannsetText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt
es ist im zweiten Teil der Antwort. Werfen Sie einen Blick
Blackbelt
Ich möchte eine Ganzzahl anzeigen. String steht für $ s und Dezimal $ d. Ganzzahl steht also für?
reegan29
Wenn Sie den "Platzhalter" meinen, können Sie verwenden %1$d. @ reegan29
Blackbelt
3
Für alle, die nach der API suchen, die die Formattypen auflistet: developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom
34

Verwechseln Sie nicht % 1 $ s und % 2 $ d in der akzeptierten Antwort. Hier sind einige zusätzliche Informationen.

  • Die Formatbezeichner können die folgende Syntax haben:

% [ argument_index$]format_specifier

  1. Der optionale Argumentindex wird als Zahl angegeben, die mit einem "$" nach "%" endet, und wählt das angegebene Argument in der Argumentliste aus. Das erste Argument wird mit "1 $" bezeichnet , das zweite mit "2 $" usw.
  2. Der erforderliche Formatbezeichner ist ein Zeichen, das angibt, wie das Argument formatiert werden soll. Die Menge der gültigen Konvertierungen für ein bestimmtes Argument hängt vom Datentyp des Arguments ab .

Beispiel

Wir werden die folgende formatierte Zeichenfolge erstellen, in die die grauen Teile programmgesteuert eingefügt werden.

Hallo Test! Sie haben 0neue Nachrichten

Ihr string resource:

<string name = "welcome_messages"> Hallo %1$s! Sie haben %2$dneue Nachrichten </ string>

Gehen Sie string substitutionwie folgt vor:

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

Hinweis:

  • % 1 $ s wird durch die Zeichenfolge "Test" ersetzt.
  • % 2 $ d wird durch die Zeichenfolge "0" ersetzt.
Rissmon Suresh
quelle
16

Ich bin auf dieselbe Flusenfehlermeldung gestoßen und habe sie auf diese Weise gelöst.

Anfangs war mein Code:

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

Ich habe den folgenden Fehler erhalten

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

Also habe ich das hinzugefügt strings.xml

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

Welches ist meine Initiale "" + ein Platzhalter für meine Nummer (Menge).

Hinweis : Meine quantityVariable wurde zuvor definiert und wollte an die Zeichenfolge angehängt werden. Mein Code als Ergebnis war

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

Danach ging mein Fehler weg. Das Verhalten in der App änderte sich nicht und meine Menge wurde weiterhin so angezeigt, wie ich es jetzt wollte, ohne einen Flusenfehler.

user1580203
quelle
10

Sie sollten diesen Thread überprüfen und einen Platzhalter wie seinen verwenden (nicht getestet).

<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);
Thomas Thiebaud
quelle
10

Verketten Sie keinen Text in Ihrer setText () -Methode. Verketten Sie , was immer Sie wollen, in einen String und fügen Sie diesen String-Wert in Ihre setText () -Methode ein.

Bsp.: richtiger Weg

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

Verketten Sie nicht innerhalb von setText () wie

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
Ashana.Jackol
quelle
Warum? Welche Vorteile hat das eine das andere?
Fureeish
4

Das Problem ist, dass Sie ""am Anfang jeder Zeichenfolge anhängen .

lint scannt Argumente, die an übergeben werden, setTextund generiert Warnungen. In Ihrem Fall ist die folgende Warnung relevant:

Erstellen Sie keine Nachrichten, indem Sie Textblöcke verketten. Solche Nachrichten können nicht richtig übersetzt werden.

wie Sie jede Zeichenfolge mit verketten "".

Entfernen Sie diese Verkettung, da die Argumente, die Sie übergeben, bereits Text sind. Sie können auch verwenden, .toString()wenn dies irgendwo anders erforderlich ist, anstatt Ihre Zeichenfolge mit zu verketten""

Rahul Tiwari
quelle
0

Wenn Sie i18n nicht unterstützen müssen, können Sie diese Flusenprüfung in Android Studio deaktivieren

Datei -> Einstellungen -> Editor -> Inspektionen -> Android -> Fussel -> TextView-Internationalisierung (deaktivieren Sie diese Option)

ssynhtn
quelle
0

Sie können dies verwenden, es funktioniert für mich

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

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

Nicht verrückt, es ist zu einfach.

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