Xem văn bản trên Android: Không ghép nối văn bản được hiển thị với setText


136

Tôi đang thiết lập văn bản bằng cách sử dụng setText () theo cách sau.

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 là sử dụng đơn giản và Thứ hai là thiết lập văn bản với định dạng văn bản.

Android Studio rất thú vị, tôi đã sử dụng Menu Analyze -> Code Cleanupvà tôi có gợi ý về hai dòng trên.

nhập mô tả hình ảnh ở đây

Không nối văn bản được hiển thị với setText. Sử dụng chuỗi tài nguyên với trình giữ chỗ. ít hơn ... (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ể của miền địa phương. Thay vào đó, hãy xem xét sử dụng định dạng Chuỗi # với thông số định dạng phù hợp (% d hoặc% f).
  • Không vượt qua một chuỗi ký tự (ví dụ "Xin chào") để hiển thị văn bản. Văn bản mã hóa cứng không thể được dịch sang các ngôn ngữ khác. Thay vào đó hãy xem xét sử dụng chuỗi tài nguyên Android.
  • Không xây dựng thư bằng cách ghép các đoạn văn bản. Những tin nhắn như vậy không thể được dịch đúng.

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


1
Điều đó có nghĩa bạn phải vượt qua chỉ là một Stringthành setText(). Vd: setText(name)thay cho setText("" + name). Bởi vì nếu bạn ghép văn bản, nó sẽ không được dịch giống như bạn sử dụng văn bản Hardcoding như thông báo thông báo
Mr Neo

Nhưng nó sẽ cho NPEnếu nameNULL
Pratik Butani

kiểm tra namekhông phải là NULLtrước khi sử dụng setText()chức năng.
Ông Neo

2
Bạn không nên kết hợp tài nguyên Chuỗi với một số giá trị, thay vào đó hãy sử dụng trình giữ chỗ trong tài nguyên chuỗi của bạn. Vì vậy, trong chuỗi XML của bạn, bạn làm: <string name="string_product_rate_with_ruppe_sign">Something %1$d</string> Và trong mã java của bạn, bạn làm một cái gì đó như thế này: prodOriginalPriceView.setText(getString(R.string.string_product_rate_with_ruppe_sign), price); (bạn có thể thực hiện định dạng trong tệp xml: [ developer.android.com/guide/topics/resource/,
CodeBreakers

Câu trả lời:


294

Tài nguyên có phiên bản getString bị quá tải, có một varargskiểu 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 chuỗi XML, với chủ sở hữu vị trí chính xác, bạn có thể sử dụng phiên bản này để truy xuất phiên bản được định dạng của Chuỗi cuối cùng. 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 Chuỗi với

 "Hello Test! you have 0 new messages"

Trong khoảng setText("" + name);

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


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

đó là trong phần thứ hai của câu trả lời. Hãy nhìn xem
Blackbelt

Tôi muốn hiển thị một Integer .String là $ s và Decimal $ d. Vậy số nguyên là viết tắt của?
reegan29

nếu bạn có nghĩa là "giữ chỗ" bạn có thể sử dụng %1$d. @ reegan29
Blackbelt

3
Đối với bất kỳ ai đang tìm kiếm API liệt kê các loại định dạng: developer.android.com/reference/java/util/Formatter#syntax
Brent Sandstrom

34

Đừ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 chỉ định định dạng có thể theo cú pháp sau:

% [ argument_index$]format_specifier

  1. Đối số tùy chọn_index được chỉ định là một số kết thúc bằng một đô la đô la sau khi có %% 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 $" , đối số thứ hai là "2 $" , v.v.
  2. Trình xác định định dạng được yêu cầu là một ký tự chỉ ra cách định dạng đối số. Tập hợp các chuyển đổi hợp lệ cho một đối số đã cho tùy thuộc vào loại dữ liệu của đối số .

Thí dụ

Chúng ta sẽ tạo chuỗi được định dạng sau trong đó các phần màu xám được chèn theo chương trình.

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

của bạn string resource:

<tên chuỗi = "welcome_messages"> Xin chào , %1$s! Bạn có %2$dtin nhắn mới </ chuỗi>

Làm string substitutionnhư được đưa ra dưới đây:

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

Ghi chú:

  • % 1 $ s sẽ được thay thế bằng chuỗi "Thử nghiệm"
  • % 2 $ d sẽ được thay thế bằng chuỗi "0"

16

Tôi chạy vào cùng một thông báo lỗi lint và giải quyết nó 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 đã gặp lỗi sau

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

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

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

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

Lưu ý : quantityBiến của tôi đã được xác định trước đó và là những gì tôi muốn nối vào chuỗi. Kết quả là mã của tôi 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 bây giờ mà không có lỗi lint.


10

Bạn nên kiểm tra chủ đề này và sử dụng một trình giữ chỗ như của mình (không được 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);

10

Không nối văn bản bên trong phương thức setText () của bạn , Ghép nối những gì bạn muốn trong một Chuỗi và đặt giá trị Chuỗi đó bên trong phương thức setText () của bạn .

ví dụ: cách chính xác

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

Không ghép nối bên trong setText () như

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

Tại sao? Người này có lợi thế gì khác?
Fureeish

4

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

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

Không xây dựng thư bằng cách ghép các đoạn văn bản. Những tin nhắn như vậy không thể được dịch đúng.

như bạn đang nối từng chuỗi với "".

xóa phần nối này vì các đố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ó yêu cầu ở bất kỳ nơi nào khác thay vì nối chuỗi của bạn với""


0

Nếu bạn không cần hỗ trợ i18n, bạn có thể vô hiệu hóa kiểm tra lint này trong Android Studio

Tệp -> Cài đặt -> Trình chỉnh sửa -> Kiểm tra -> Android -> Lint -> Quốc tế hóa TextView (bỏ chọn này)


0

Bạn có thể sử dụng nó, nó làm việc cho tôi

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

Đừng Mad, nó quá đơn giản.

String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
            mytextview.setText(result);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.