Android TextView:“不要连接使用setText显示的文本”


136

我通过以下方式使用setText()设置文本。

prodNameView.setText("" + name);

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

因为一个是简单的用法,第二个是使用格式化文本设置文本。

Android Studio非常有趣,我使用了Menu,Analyze -> Code Cleanup并且在上面两行得到了建议。

在此处输入图片说明

不要连接使用setText显示的文本。将资源字符串与占位符一起使用。更少...(Ctrl + F1)

调用TextView#setText时:

  • 永远不要调用Number#toString()格式化数字;它不会正确处理分数分隔符和特定于语言环境的数字。考虑改用具有正确格式规范(%d或%f)的String#format。
  • 不要传递字符串文字(例如“ Hello”)来显示文本。硬编码文本无法正确翻译为其他语言。考虑改用Android资源字符串。
  • 不要通过串联文本块来构建消息。此类消息无法正确翻译。

我能为此做什么?任何人都可以帮助解释这是什么,我该怎么办?


1
这意味着您只能将String传入setText()。例如:setText(name)代替setText("" + name)。因为如果您串联文本,将不会像使用硬编码文本那样将其转换为消息通知
Neo Neo先生

但它会给NPE如果nameNULL
PRATIK Butani

检查name是不是NULL使用以前setText()的功能。
Neo Neo先生

2
您不应将字符串资源与某些值连接在一起,而应在字符串资源中使用占位符。因此,在您string.xml你: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> 而在Java代码中,你做这样的事情: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (你可以做在XML文件中的格式:[ developer.android.com/guide/topics/resources/...
密码破译专家

Answers:


294

资源具有的getString的get重载版本,这需要一个varargs类型Object的getString(INT,java.lang.Object中...) 。如果使用正确的占位符正确地在string.xml中设置了字符串,则可以使用此版本来检索最终String的格式化版本。例如

<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"

关于 setText("" + name);

您的第一个示例prodNameView.setText("" + name);对我没有任何意义。TextView能够处理空值。如果name为null,则不会绘制文本。


1
假设在BigDecimal上您将调用浮点值:%1$f在string.xml中添加到您的字符串中,然后调用setText(getString(R.string.string_product_rate_with_ruppe_sign, new BigDecimal(price).setScale(2, RoundingMode.UP).floatValue() ));
Blackbelt 2015年

这是答案的第二部分。看看
Blackbelt

我想显示一个整数.String代表$ s和十进制$ d。那么整数代表什么?
reegan29

如果您是指“占位符”,则可以使用%1$d。@ reegan29
黑带

3
对于寻找API列出格式类型的任何人:developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom,

34

不要在接受的答案中与 %1 $ s%2 $ d混淆。以下是一些其他信息。

  • 格式说明符可以具有以下语法:

%[ argument_index$]format_specifier

  1. 可选的arguments_index被指定为以“%”后面的“ $”结尾的数字,并在参数列表中选择指定的参数。第一个参数由“ 1 $”引用,第二个参数由“ 2 $”等等。
  2. 必需的格式说明符是一个字符,指示应如何格式化自变量。给定参数的有效转换集取决于参数的数据类型。

我们将创建以下格式的字符串,其中以编程方式插入灰色部分。

你好Test!你有0新消息

您的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”代替

16

我遇到了相同的棉绒错误消息,并以这种方式解决了。

最初,我的代码是:

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

此后,我的错误消失了。应用程序中的行为没有改变,我的数量继续显示,直到现在为止都没有出现棉绒错误。


10

您应该检查该线程,并使用一个类似他的占位符(未经测试)

<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()方法,串联你想在什么都字符串,并把你的内部字符串值的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));

为什么?另一方有什么优势?
Fureeish

4

问题是因为您要追加""到每个字符串的开头。

lint会扫描要传递给的参数setText并会生成警告,在您的情况下,以下警告是相关的:

不要通过串联文本块来构建消息。此类消息无法正确翻译。

当您使用串联每个字符串时""

删除此串联,因为您要传递的参数已经是文本。另外,您可以.toString()在其他任何地方使用(如果需要的话),而不必将字符串与""


0

如果您不需要支持i18n,则可以在Android Studio中禁用此皮棉检查

文件->设置->编辑器->检查-> Android-> Lint-> TextView国际化(取消选中此选项)


0

您可以使用它,它对我有用

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

别疯了,太简单了。

String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
            mytextview.setText(result);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.