web-dev-qa-db-ja.com

Android TextView:「setTextで表示されたテキストを連結しないでください」

私は次の方法でsetText()を使用してテキストを設定しています。

prodNameView.setText("" + name);

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

その中でFirst1つは単純な使用で、Second1つはテキストの書式設定。

Android Studioは非常に興味深いので、MenuAnalyze -> Code Cleanupを使用し、上記の2行のような提案を受けました。

enter image description here

SetTextで表示されるテキストを連結しないでください。プレースホルダーでリソース文字列を使用します。少ない...(Ctrl + F1)

呼び出すときTextView#setText:

  • Number#toString()を呼び出して数値をフォーマットしないでください。分数の区切り文字とロケール固有の数字を適切に処理しません。代わりに、適切な形式仕様(%dまたは%f)を使用したString#formatの使用を検討してください。
  • 文字列リテラル(例:「Hello」)を渡してテキストを表示しないでください。ハードコードされたテキストは、他の言語に適切に翻訳できません。代わりにAndroidリソース文字列の使用を検討してください。
  • テキストチャンクを連結してメッセージを作成しないでください。このようなメッセージは適切に翻訳できません。

私はこれのために何ができますか?誰が物事が何であり、私は何をすべきかを説明するのを助けることができますか?

リソースには、タイプvarargsObjectを使用するgetStringのgetオーバーロードバージョンがあります: getString(int、Java.lang.Object ...) 。正しいプレースホルダーを使用して、strings.xmlで文字列を正しく設定すると、このバージョンを使用して、最終的な文字列のフォーマットされたバージョンを取得できます。例えば。

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

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

Androidは次の文字列を返します

 Hello Test! you have 0 new messages

AboutsetText("" + name);

最初の例、prodNameView.setText("" + name);は私には意味がありません。 TextViewはnull値を処理できます。名前がnullの場合、テキストは描画されません。

238
Blackbelt

受け入れられた回答の%1 $ sおよび%2 $ dと混同しないでください。いくつかの追加情報があります。

  • 形式指定子は次の構文にすることができます。

%[argument_index $] format_specifier

  1. オプションのargument_indexは、「%」の後に「$」で終わる番号として指定され、引数リストで指定された引数を選択します。最初の引数は"1 $"で参照され、2番目の引数は"2 $"で参照されます。
  2. 必須のformat specifierは、引数のフォーマット方法を示す文字です。特定の引数の有効な変換のセットは、引数のデータ型に依存します

灰色の部分がプログラムで挿入される次のフォーマットされた文字列を作成します。

こんにちはTest0個の新しいメッセージがあります

あなたのstring resource

<string name = "welcome_messages">こんにちは、%1$s%2$d個の新しいメッセージがあります</ string>

以下に示すようにstring substitutionを実行します。

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

注意:

  • %1 $ sは、文字列 "Test"によって置き換えられます
  • %2 $ dは、文字列 "0"によって置き換えられます
22
Rissmon Suresh

同じlintエラーメッセージに遭遇し、この方法で解決しました。

最初は私のコードは:

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

次のエラーが表示されました

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

そこで、これをstrings.xmlに追加しました

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

これは私の最初の "" +私の番号(数量)のプレースホルダーです。

quantity変数は以前に定義されており、文字列に追加したかったものです。結果として私のコードは

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

この後、私のエラーはなくなりました。アプリの動作は変わらず、リントエラーが発生することなく、必要に応じて数量が表示され続けました。

13
user1580203

これを確認する必要があります thread 彼のようなプレースホルダーを使用します(テストされていません)

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

setText()メソッド内でテキストを連結しないでください。Stringで必要なものを連結し、そのストリング値をsetText()内に入れてください。方法。

例:正しい方法

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

しない setText()内で連結

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
8
Ashana.Jackol

問題は、すべての文字列の先頭に""を追加しているためです。

lintはsetTextに渡される引数をスキャンし、警告を生成します。この場合、次の警告が関連します。

テキストチャンクを連結してメッセージを作成しないでください。このようなメッセージは適切に翻訳できません。

すべての文字列を""で連結しているため。

渡す引数はすでにテキストであるため、この連結を削除します。また、文字列を""と連結する代わりに、他で必要な場合は.toString()を使用できます。

4
Rahul Tiwari

I18nをサポートする必要がない場合は、Android Studioでこのリントチェックを無効にできます

ファイル->設定->エディタ->インスペクション-> Android-> Lint-> TextView国際化(これをチェック解除)

0
ssynhtn