Android TextView: “Jangan menyatukan teks yang ditampilkan dengan setText”

136

Saya mengatur teks menggunakan setText () dengan cara berikut.

prodNameView.setText("" + name);

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

Dalam yang pertama adalah penggunaan sederhana dan yang kedua adalah pengaturan teks dengan format teks.

Android Studio sangat menarik, saya menggunakan Menu Analyze -> Code Cleanupdan saya mendapat saran di atas dua baris seperti.

masukkan deskripsi gambar di sini

Jangan menyatukan teks yang ditampilkan dengan setText. Gunakan string sumber daya dengan placeholder. kurang ... (Ctrl + F1)

Saat memanggil TextView # setText:

  • Jangan pernah panggil Nomor # toString () untuk memformat angka; itu tidak akan menangani pemisah fraksi dan angka spesifik lokal dengan benar. Pertimbangkan untuk menggunakan format String # dengan spesifikasi format yang tepat (% d atau% f).
  • Jangan melewatkan string literal (mis. "Hello") untuk menampilkan teks. Teks yang dikode keras tidak dapat diterjemahkan dengan benar ke bahasa lain. Pertimbangkan menggunakan string sumber daya Android sebagai gantinya.
  • Jangan membuat pesan dengan menggabungkan potongan teks. Pesan semacam itu tidak dapat diterjemahkan dengan benar.

Apa yang bisa saya lakukan untuk ini? Adakah yang bisa membantu menjelaskan benda apa itu dan apa yang harus saya lakukan?

Pratik Butani
sumber
1
Itu berarti Anda harus lulus hanya Stringmenjadi setText(). Contoh: setText(name)sebagai pengganti setText("" + name). Karena jika Anda menggabungkan teks, itu tidak akan diterjemahkan seperti Anda menggunakan teks Hardcoded sebagai pesan memberitahukan
Mr Neo
Tapi itu akan memberikan NPEjika nameadalahNULL
Pratik Butani
periksa nametidak NULLsebelum menggunakan setText()fungsi.
Tn. Neo
2
Anda tidak boleh menyatukan sumber daya String dengan beberapa nilai, melainkan menggunakan placeholder di sumber daya string Anda. Jadi dalam string.xml Anda, Anda melakukannya: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> Dan dalam kode java Anda, Anda melakukan sesuatu seperti ini: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (Anda dapat melakukan format pada file xml: [ developer.android.com/guide/topics/resources/…
CodeBreakers

Jawaban:

294

Resource memiliki versi getString yang kelebihan beban yang menggunakan varargstipe Object: getString (int, java.lang.Object ...) . Jika Anda menyiapkan string dengan benar di strings.xml, dengan penampung yang benar, Anda dapat menggunakan versi ini untuk mengambil versi terformat dari String akhir Anda. Misalnya

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

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

Android akan mengembalikan sebuah String dengan

 "Hello Test! you have 0 new messages"

Tentang setText("" + name);

Contoh pertama Anda, prodNameView.setText("" + name);tidak masuk akal bagi saya. TextView mampu menangani nilai null. Jika nama adalah nol, tidak ada teks yang akan ditarik.

Sabuk hitam
sumber
1
dengan asumsi bahwa pada BigDecimal Anda, Anda akan memanggil nilai float: Tambahkan %1$fke string Anda, di strings.xml dan kemudian panggilsetText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt
itu ada di bagian kedua dari jawabannya. Silahkan lihat
Blackbelt
Saya ingin menunjukkan Integer .String berdiri $ s dan Desimal $ d. Jadi bilangan bulat singkatan?
mulai lagi
jika Anda maksudkan "placeholder" yang dapat Anda gunakan %1$d. @ reegan29
Blackbelt
3
Bagi siapa pun yang mencari API yang mencantumkan jenis format: developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom
34

Jangan bingung dengan % 1 $ s dan % 2 $ d dalam jawaban yang diterima. Berikut adalah beberapa informasi tambahan.

  • Penentu format dapat berupa sintaks berikut:

% [ argument_index$]format_specifier

  1. Argumen opsionalindeks ditentukan sebagai angka yang diakhiri dengan "$" setelah "%" dan memilih argumen yang ditentukan dalam daftar argumen. Argumen pertama dirujuk oleh "1 $" , yang kedua oleh "2 $" , dll.
  2. Penentu format yang diperlukan adalah karakter yang menunjukkan bagaimana argumen harus diformat. Set konversi yang valid untuk argumen yang diberikan tergantung pada tipe data argumen .

Contoh

Kami akan membuat string berformat berikut di mana bagian abu-abu dimasukkan secara terprogram.

Halo Test! Anda memiliki 0pesan baru

Anda string resource:

<String name = "welcome_messages"> Halo, %1$s! Anda memiliki %2$dpesan baru </ string>

Lakukan string substitutionseperti yang diberikan di bawah ini:

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

catatan:

  • % 1 $ s akan diganti dengan string "Tes"
  • % 2 $ d akan diganti dengan string "0"
Rissmon Suresh
sumber
16

Saya mengalami pesan kesalahan serat yang sama dan menyelesaikannya dengan cara ini.

Awalnya kode saya adalah:

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

Saya mendapat kesalahan berikut

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

Jadi, saya menambahkan ini ke strings.xml

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

Yang merupakan "" awal + tempat saya untuk nomor saya (kuantitas).

Catatan : quantityVariabel saya sebelumnya didefinisikan dan saya ingin menambahkan string. Kode saya sebagai hasilnya

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

Setelah ini, kesalahan saya hilang. Perilaku dalam aplikasi tidak berubah dan kuantitas saya terus ditampilkan seperti yang saya inginkan sekarang tanpa kesalahan serat.

pengguna1580203
sumber
10

Anda harus memeriksa utas ini dan menggunakan penampung seperti miliknya (tidak diuji)

<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 Tiebaud
sumber
10

Jangan menyatukan teks di dalam metode setText () Anda , gabungkan apa yang Anda inginkan dalam sebuah String dan masukkan nilai String itu ke dalam metode setText () Anda .

mis: cara yang benar

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

Jangan menyatukan di dalam setText () seperti

text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
Ashana.Jackol
sumber
Mengapa? Apa kelebihan yang satu memiliki yang lain?
Fureeish
4

masalahnya adalah karena Anda menambahkan ""pada awal setiap string.

lint akan memindai argumen yang diteruskan ke setTextdan akan menghasilkan peringatan, dalam kasus Anda peringatan berikut relevan:

Jangan membuat pesan dengan menggabungkan potongan teks. Pesan semacam itu tidak dapat diterjemahkan dengan benar.

karena Anda menggabungkan setiap string dengan "".

hapus gabungan ini karena argumen yang Anda berikan sudah berupa teks. Juga, Anda dapat menggunakan .toString()jika diperlukan di tempat lain alih-alih menyatukan string Anda""

Rahul Tiwari
sumber
0

Jika Anda tidak perlu mendukung i18n, Anda dapat menonaktifkan pemeriksaan serat ini di Android Studio

File -> Pengaturan -> Editor -> Inspeksi -> Android -> Lint -> TextView Internasionalisasi (hapus centang ini)

ssynhtn
sumber
0

Anda dapat menggunakan ini, ini berfungsi untuk saya

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

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

Jangan Gila, Terlalu Sederhana.

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