68

Tôi đang đặt văn bản bằng cách sử dụng setText() bằng cách sau.Android TextView: "Không ghép nối văn bản được hiển thị với setText"

prodNameView.setText("" + name); 

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

Trong đó Đầu tiên một là sử dụng đơn giản và Second ai thiết lập văn bản với văn bản định dạng.

Android Studio thật thú vị, tôi đã sử dụng Menu Analyze -> Code Cleanup và tôi đã nhận được đề xuất về hai dòng như trên.

enter image description here

Đừng nối văn bản hiển thị với setText. Sử dụng chuỗi tài nguyên với trình giữ chỗ. ít ... (Ctrl + F1)

Khi gọi TextView # setText:

  • Không bao giờ gọi Số # toString() để định dạng số; nó sẽ không xử lý các dấu tách phân số và các chữ số cụ thể theo ngôn ngữ cụ thể. Hãy xem xét sử dụng định dạng Chuỗi # với thông số kỹ thuật định dạng thích hợp (% d hoặc% f) thay thế.
  • Không được chuyển một chuỗi chữ (ví dụ: "Hello") để hiển thị văn bản. Không thể dịch chính xác văn bản được mã hóa sang các ngôn ngữ khác. Cân nhắc sử dụng chuỗi tài nguyên Android để thay thế.
  • Không xây dựng thư bằng cách ghép các đoạn văn bản. Những thông điệp như vậy không thể được dịch đúng.

Tôi có thể làm gì cho điều này? Bất cứ ai cũng có thể giúp giải thích những gì là điều gì và tôi nên làm gì?

+1

Điều đó có nghĩa bạn nên chỉ chuyển một 'String' vào' setText() '. Ví dụ: 'setText (name)' thay cho 'setText (" "+ name)'. Bởi vì nếu bạn nối văn bản, nó sẽ không được dịch như bạn sử dụng văn bản Hardcoded như thông báo thông báo –

+0

Nhưng nó sẽ cho 'NPE' nếu' name' là 'NULL' –

+0

kiểm tra' name' không phải là 'NULL' trước khi sử dụng' setText() 'hàm. –

Trả lời

181

Tài nguyên có phiên bản getString bị quá tải chiếm mất varargs loại Object: getString(int, java.lang.Object...). Nếu bạn thiết lập chính xác chuỗi của mình trong strings.xml, với các trình giữ chỗ chính xác, bạn có thể sử dụng phiên bản này để truy xuất phiên bản đã định dạng của Chuỗi cuối cùng của bạn. Ví dụ.

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

sử dụng getString(R.string.welcome_message, "Test", 0);

android sẽ trả về một String với

Hello Test! you have 0 new messages 

VềsetText("" + name);

Ví dụ đầu tiên của bạn, prodNameView.setText("" + name); không thực hiện bất kỳ ý nghĩa với tôi. TextView có thể xử lý các giá trị null. Nếu tên là null, không có văn bản nào được vẽ.

+0

giả định rằng trên BigDecimal của bạn, bạn sẽ gọi giá trị float: Thêm '% 1 $ f' vào chuỗi của bạn, trong strings.xml và sau đó gọi' setText (getString (R.string.string_product_rate_with_ruppe_sign, new BigDecimal (price) .setScale (2, RoundingMode .UP) .floatValue())); ' – Blackbelt

+0

nó nằm trong phần thứ hai của câu trả lời. Có một cái nhìn – Blackbelt

+3

Cảm ơn bạn rất nhiều vì câu trả lời được đánh giá cao của bạn. :) Được bình chọn + Được chấp nhận. Giữ #Textviewing;) –

5

Bạn nên kiểm tra này thread và sử dụng một placeholder như một mình (không kiểm tra)

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

vấn đề là bởi vì bạn đang phụ "" vào đầu mỗi chuỗi.

lint sẽ quét đối số được truyền cho setText và sẽ tạo ra cảnh báo, trong trường hợp của bạn sau cảnh báo là có liên quan:

Không xây dựng các thông điệp bằng concatenating khối văn bản. Các thông điệp như vậy có thể không được đúng cách dịch.

khi bạn đang ghép nối mọi chuỗi với "".

xóa kết nối này khi đối số bạn đang truyền đã là văn bản. Ngoài ra, bạn có thể sử dụng .toString() nếu cần bất kỳ nơi nào khác thay vì ghép chuỗi của bạn với ""

9

Tôi chạy vào cùng một thông báo lỗi lint và giải quyết theo cách này.

Ban đầu mã của tôi là:

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

Tôi đã nhận lỗi sau

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

Vì vậy, tôi đã thêm này để strings.xml

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

Đó là ban đầu của tôi "" + a trình giữ chỗ cho số của tôi (số lượng).

Lưu ý: Biến số quantity trước đây của tôi đã được xác định và là thứ tôi muốn nối thêm vào chuỗi. Mã của tôi là kết quả là

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

Sau này, lỗi của tôi biến mất. Hành vi trong ứng dụng không thay đổi và số lượng của tôi tiếp tục hiển thị như tôi muốn đến bây giờ mà không có lỗi lint.

3

Đừng nhầm lẫn với % 1 $ s% 2 $ d trong câu trả lời được chấp nhận.Đây là một vài thông tin bổ sung.

  • Các specifiers định dạng có thể được cú pháp sau:

% [argument_index $] format_specifier

  1. Các tùy chọn argument_index được quy định như một số kết thúc với “$” sau “%” và chọn đối số được chỉ định trong danh sách đối số. Đối số đầu tiên được tham chiếu bởi "1 $", thứ hai bởi "2 $" vv
  2. các yêu cầu format specifier là một nhân vật chỉ ra cách lập luận nên được định dạng. Tập hợp các chuyển đổi hợp lệ cho một đối số đã cho phụ thuộc vào kiểu dữ liệu của đối số.

Ví dụ

Chúng tôi sẽ tạo ra chuỗi định dạng sau đây những phần màu xám được chèn vào lập trình.

Xin chào Test! bạn có 0 tin nhắn mới

string resource của bạn:

< string name = "welcome_messages"> Xin chào, %1$s! Bạn có %2$d tin nhắn mới </string>

Làm string substitution như đưa ra dưới đây:

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

Lưu ý:

  • % 1 $ s sẽ substitude bởi chuỗi "Test"
  • % 2 $ d sẽ substitude bởi chuỗi "0"
Các vấn đề liên quan