Android TextView : "Do not concatenate text displayed with setText"

AndroidConcatenationTextviewString Concatenation

Android Problem Overview


I am setting text using setText() by following way.

prodNameView.setText("" + name);

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

In that First one is simple use and Second one is setting text with formatting text.

Android Studio is so much interesting, I used Menu Analyze -> Code Cleanup and i got suggestion on above two lines like.

enter image description here

> Do not concatenate text displayed with setText. Use resource string > with placeholders. less... (Ctrl+F1) > > When calling TextView#setText: > > - Never call Number#toString() to format numbers; it will not handle fraction separators and locale-specific digits properly. Consider > using String#format with proper format specifications (%d or %f) > instead. > - Do not pass a string literal (e.g. "Hello") to display text. Hardcoded text can not be properly translated to other languages. > Consider using Android resource strings instead. > - Do not build messages by concatenating text chunks. Such messages can not be properly translated.

What I can do for this? Anyone can help explain what the thing is and what should I do?

Android Solutions


Solution 1 - Android

Resource has the get overloaded version of getString which takes a varargs of type Object: getString(int, java.lang.Object...). If you setup correctly your string in strings.xml, with the correct place holders, you can use this version to retrieve the formatted version of your final String. E.g.

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

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

android will return a String with

 "Hello Test! you have 0 new messages"

About setText("" + name);

Your first Example, prodNameView.setText("" + name); doesn't make any sense to me. The TextView is able to handle null values. If name is null, no text will be drawn.

Solution 2 - Android

Don't get confused with %1$s and %2$d in the accepted answer.Here is a few extra information.

  • The format specifiers can be of the following syntax:

> %[argument_index$]format_specifier

  1. The optional argument_index is specified as a number ending with a “$” after the “%” and selects the specified argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
  2. The required format specifier is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.

Example

We will create the following formatted string where the gray parts are inserted programmatically.

> Hello Test! you have 0 new messages

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

Do the string substitution as given below:

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

Note:

  • %1$s will be substituted by the string "Test"
  • %2$d will be substituted by the string "0"

Solution 3 - Android

I ran into the same lint error message and solved it this way.

Initially my code was:

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

I got the following error

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

So, I added this to strings.xml

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

Which is my initial "" + a placeholder for my number(quantity).

Note: My quantity variable was previously defined and is what I wanted to append to the string. My code as a result was

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

After this, my error went away. The behavior in the app did not change and my quantity continued to display as I wanted it to now without a lint error.

Solution 4 - Android

Do not concatenate text inside your setText() method, Concatenate what ever you want in a String and put that String value inside your setText() method.

ex: correct way

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

Do not concatenate inside setText() like

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

Solution 5 - Android

You should check this thread and use a placeholder like his one (not tested)

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

Solution 6 - Android

the problem is because you are appending "" at the beginning of every string.

lint will scan arguments being passed to setText and will generate warnings, in your case following warning is relevant:

> Do not build messages by > concatenating text chunks. Such messages can not be properly > translated.

as you are concatenating every string with "".

remove this concatenation as the arguments you are passing are already text. Also, you can use .toString() if at all required anywhere else instead of concatenating your string with ""

Solution 7 - Android

Don't Mad, It's too Simple.

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

Solution 8 - Android

You can use this , it works for me

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

Solution 9 - Android

I fixed it by using String.format

befor :

textViewAddress.setText("Address"+address+"\n"+"nCountry"+"\n"+"City"+"city"+"\n"+"State"+"state")

after :

textViewAddress.setText(
     String.format("Address:%s\nCountry:%s\nCity:%s\nState:%s", address, country, city, state));
       

Solution 10 - Android

If you don't need to support i18n, you can disable this lint check in Android Studio

File -> Settings -> Editor -> Inspections -> Android -> Lint -> TextView Internationalization(uncheck this)

Solution 11 - Android

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

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

Solution 12 - Android

if it is textView you can use like that : myTextView.text = ("Hello World") in editText you can use myTextView.setText("Hello World")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPratik ButaniView Question on Stackoverflow
Solution 1 - AndroidBlackbeltView Answer on Stackoverflow
Solution 2 - AndroidRissmon SureshView Answer on Stackoverflow
Solution 3 - Androiduser1580203View Answer on Stackoverflow
Solution 4 - AndroidAshana.JackolView Answer on Stackoverflow
Solution 5 - AndroidThomasThiebaudView Answer on Stackoverflow
Solution 6 - AndroidRahul TiwariView Answer on Stackoverflow
Solution 7 - AndroidmwaqasView Answer on Stackoverflow
Solution 8 - Androidbahman karamiView Answer on Stackoverflow
Solution 9 - Androidjenos konView Answer on Stackoverflow
Solution 10 - AndroidssynhtnView Answer on Stackoverflow
Solution 11 - AndroidSkorpENView Answer on Stackoverflow
Solution 12 - AndroidAbdulkerim YıldırımView Answer on Stackoverflow