Android TextView: "setText ile görüntülenen metni birleştirmeyin"


137

SetText () kullanarak metni aşağıdaki şekilde ayarlıyorum .

prodNameView.setText("" + name);

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

Bunda Birincisi basit kullanımdır ve İkincisi metni formatlama ile ayarlamaktır.

Android Studio çok ilginç, Menü kullandım Analyze -> Code Cleanupve iki satırın üstünde önerim var.

görüntü açıklamasını buraya girin

SetText ile görüntülenen metni birleştirmeyin. Yer tutucularla kaynak dizesi kullanın. daha az ... (Ctrl + F1)

Ne zaman arayarak TextView'un # setText:

  • Numaraları biçimlendirmek için No # toString () 'i asla çağırmayın; kesir ayırıcıları ve yerel ayara özgü basamakları düzgün şekilde işlemez. Bunun yerine, uygun biçim belirtimlerine (% d veya% f) sahip Dize # biçimini kullanmayı düşünün.
  • Metni görüntülemek için değişmez bir dize (örn. "Merhaba") iletmeyin. Sabit kodlanmış metin diğer dillere doğru bir şekilde çevrilemez. Bunun yerine Android kaynak dizelerini kullanmayı düşünün.
  • Metin parçalarını birleştirerek mesaj oluşturmayın. Bu tür mesajlar doğru bir şekilde tercüme edilemez.

Bunun için ne yapabilirim? Herkes bir şeyin ne olduğunu ve ne yapmam gerektiğini açıklamaya yardımcı olabilir?


1
Bu, yalnızca bir Stringgiriş yapmanız gerektiği anlamına gelir setText(). Ör: setText(name)yerine setText("" + name). Çünkü metni birleştirirseniz, mesajın bildirdiği gibi Sabit Kodlu metni kullandığınız gibi çevrilmeyecektir
Mr Neo

Ama verecektir NPEeğer nameolduğunuNULL
Pratik Butani

kontrol işlevi kullanılmadan önce nameyapılmaz . NULLsetText()
Mr Neo

2
Bir String kaynağını bir değerle birleştirmemelisiniz, bunun yerine dize kaynağınızda yer tutucular kullanın. Yani string.xml'nizde yaparsınız: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> Ve java kodunuzda şöyle bir şey yaparsınız: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (biçimlendirmeyi xml dosyasında yapabilirsiniz: [ developer.android.com/guide/topics/resources/…
CodeBreakers

Yanıtlar:


295

Kaynak bir alan getString get aşırı sürüme sahip varargsÇeşidi Object: getString (int, java.lang.Object ...) . Dizenizi strings.xml'de doğru yer tutucularla doğru bir şekilde kurarsanız, son Dizenizin biçimlendirilmiş sürümünü almak için bu sürümü kullanabilirsiniz. Örneğin

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

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

android ile bir String döndürür

 "Hello Test! you have 0 new messages"

hakkında setText("" + name);

İlk Örneğiniz prodNameView.setText("" + name);bana hiç mantıklı gelmiyor. TextView, boş değerleri işleyebilir. İsim boş ise, metin çizilmeyecektir.


1
BigDecimal'inizde float değerini çağıracağınızı varsayarak: Dizinize ekleyin %1$f, strings.xml'de ve ardındansetText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt

cevabın ikinci kısmında. Bir göz atın
Blackbelt

Bir Tamsayı göstermek istiyorum .String $ s ve Decimal $ d olarak duruyor. Yani tamsayı mı?
reegan29

"yer tutucuyu" kastediyorsanız, kullanabilirsiniz %1$d. @ reegan29
Blackbelt

3
Biçim

34

Kabul edilen cevapta % 1 $ s ve % 2 $ d ile karıştırmayın . İşte birkaç ek bilgi.

  • Biçim belirleyicileri aşağıdaki sözdiziminde olabilir:

% [ argument_index$]format_specifier

  1. İsteğe bağlı argument_index , "%" dan sonra "$" ile biten bir sayı olarak belirtilir ve argüman listesinde belirtilen argümanı seçer. İlk bağımsız değişkene "1 $" , ikinciye "2 $" vb. Başvurulur .
  2. Gerekli biçim belirticisi , bağımsız değişkenin nasıl biçimlendirilmesi gerektiğini belirten bir karakterdir. Belirli bir bağımsız değişken için geçerli dönüştürme kümesi, bağımsız değişkenin veri türüne bağlıdır .

Misal

Gri kısımların programlı olarak eklendiği aşağıdaki biçimlendirilmiş dizeyi oluşturacağız.

Merhaba Test! Sahip olduğunuz 0yeni mesajları

Sizin string resource:

<string name = "welcome_messages"> Merhaba %1$s! You have %2$dyeni mesajları </ string>

Do string substitutionaşağıda verildiği gibi:

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

Not:

  • % 1 $ s, "Test" dizesi ile değiştirilecek
  • % 2 $ d, "0" dizesiyle değiştirilecek

16

Aynı tüy bırakmayan hata mesajıyla karşılaştım ve bu şekilde çözdüm.

Başlangıçta kodum şuydu:

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

Aşağıdaki hatayı aldım

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

Bu yüzden bunu ekledim strings.xml

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

Bu benim ilk "" + numaram (miktar) için bir yer tutucudur.

Not : quantityDeğişkenim önceden tanımlanmıştı ve dizeye eklemek istediğim şey buydu. Sonuç olarak kodum

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

Bundan sonra hatam ortadan kalktı. Uygulamadaki davranış değişmedi ve miktarım şimdi istediğim gibi tiftik hatası olmadan görüntülenmeye devam etti.


10

Bu ileti dizisini kontrol etmeli ve onunki gibi bir yer tutucu kullanmalısınız (test edilmemiş)

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

10

SetText () yönteminizin içindeki metni bitiştirmeyin, bir String'de istediğinizi birleştirin ve bu String değerini setText () yönteminizin içine koyun .

ör: doğru yol

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

Yapmayın gibi) (concatenate iç setText

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

Neden? Birinin diğerine ne gibi avantajları var?
Fureeish

4

sorun, ""her dizenin başına eklemenizdir .

lint, iletilen argümanları tarayacak setTextve sizin durumunuzda aşağıdaki uyarılar ile ilgili olan uyarılar oluşturacaktır:

Metin parçalarını birleştirerek mesaj oluşturmayın. Bu tür mesajlar doğru bir şekilde tercüme edilemez.

her dizeyi bitiştirirken "".

ilettiğiniz argümanlar zaten metin olduğundan, bu birleştirmeyi kaldırın. Ayrıca, .toString()dizenizi ile birleştirmek yerine herhangi bir yerde gerekliyse kullanabilirsiniz .""


0

İ18n'yi desteklemeniz gerekmiyorsa, bu tüy bırakma kontrolünü Android Studio'da devre dışı bırakabilirsiniz.

Dosya -> Ayarlar -> Düzenleyici -> Denetimler -> Android -> Lint -> TextView Internationalization (bunun işaretini kaldırın)


0

Bunu kullanabilirsin, benim için çalışıyor

title.setText(MessageFormat.format("{0} {1}", itemList.get(position).getOppName(), itemList.get(position).getBatchNum()));

0
prodNameView.setText("" + name); //this produce lint error

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

-1

Deli Etmeyin, Çok Basit.

String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
            mytextview.setText(result);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.