Có thể tự động thêm String vào String.xml trong Android không?


495

Có thể có các trình giữ chỗ trong các giá trị chuỗi trong string.xmlđó có thể được gán các giá trị trong thời gian chạy không?

Thí dụ:

một số chuỗi PLACEHOLDER1 một số chuỗi khác



@HarishGyanani Không, cái này cũ hơn, cái này nên được hợp nhất với cái này thay vào đó
Danh

Câu trả lời:


1035

Định dạng và tạo kiểu

Có, xem phần sau từ Chuỗi Tài nguyên: Định dạng và Tạo kiểu

Nếu bạn cần định dạng chuỗi của mình bằng cách sử dụng String.format(String, Object...), thì bạn có thể làm như vậy bằng cách đặt đối số định dạng của mình vào tài nguyên chuỗi. Ví dụ: với tài nguyên sau:

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

Trong ví dụ này, chuỗi định dạng có hai đối số: %1$slà một chuỗi và %2$dlà số thập phân. Bạn có thể định dạng chuỗi với các đối số từ ứng dụng của bạn như thế này:

Resources res = getResources();
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);

Cách sử dụng cơ bản

Lưu ý rằng getStringcó quá tải sử dụng chuỗi dưới dạng chuỗi định dạng:

String text = res.getString(R.string.welcome_messages, username, mailCount);

Số nhiều

Nếu bạn cần xử lý số nhiều, hãy sử dụng:

<plurals name="welcome_messages">
    <item quantity="one">Hello, %1$s! You have a new message.</item>
    <item quantity="other">Hello, %1$s! You have %2$d new messages.</item>
</plurals>

Thông số đầu tiên mailCountđược sử dụng để quyết định sử dụng định dạng nào (đơn hoặc số nhiều), các thông số khác là sự thay thế của bạn:

Resources res = getResources();
String text = res.getQuantityString(R.plurals.welcome_messages, mailCount, username, mailCount);

Xem Tài nguyên chuỗi: Số nhiều để biết thêm chi tiết.


61
Cuộc gọi String.format trong mẫu mã đầu tiên thực sự không cần thiết, Resources.getString () hỗ trợ định dạng, xem: developer.android.com/reference/android/content/res/ tựa, java.lang.Object ...)
Arnaud

16
đối với số nhiều trong String.xml, bạn cần cung cấp id dưới dạng R.plurals.welcome_messages thay vì
R.opes.welcome_messages

điều số nhiều chỉ trả về chuỗi mục cuối cùng ... bất kỳ ý tưởng nào có thể lấy chuỗi bổ sung.
CoDe

1
Khi sử dụng phương pháp này để định dạng chuỗi của bạn, nó đã xóa bất kỳ thẻ meta nào bạn có thể đã sử dụng như siêu liên kết, v.v. có thể có trong văn bản chuỗi xml
Jonathan

4
Chuỗi là viết tắt của% 1 $ s, thập phân cho% 2 $ d và số nguyên là gì? Ý nghĩa% 1,% 2. Là cách đếm tham số này ?. Nếu tôi muốn tham số thứ ba Được đề cập đến% 3?
reegan29

260

Bổ sung trả lời

Khi tôi lần đầu tiên nhìn thấy %1$s%2$dtrong câu trả lời được chấp nhận, nó không có ý nghĩa gì. Đây là một lời giải thích thêm một chút.

Chúng được gọi là specifier định dạng. Trong chuỗi xml, chúng ở dạng

%[parameter_index$][format_type] 
  • % : Dấu phần trăm đánh dấu sự bắt đầu của trình xác định định dạng.
  • chỉ số tham số : Đây là một số theo sau là một ký hiệu đô la. Nếu bạn có ba tham số mà bạn muốn chèn vào chuỗi, sau đó họ sẽ được gọi là 1$, 2$, và 3$. Thứ tự bạn đặt chúng trong chuỗi tài nguyên không thành vấn đề, chỉ có thứ tự bạn cung cấp các tham số.
  • loại định dạng : Có rất nhiều cách mà bạn có thể định dạng mọi thứ ( xem tài liệu ). Dưới đây là một số phổ biến:

    • s chuỗi
    • d số nguyên thập phân
    • f số điểm nổi

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.

Em gái tôi Mary12tuổi.

chuỗi tệp

<string name="my_xml_string">My sister %1$s is %2$d years old.</string>

MyActivity.java

String myString = "Mary";
int myInt = 12;
String formatted = getString(R.string.my_xml_string, myString, myInt);

Ghi chú

  • Tôi có thể sử dụng getStringvì tôi đang ở trong một Hoạt động. Bạn có thể sử dụng context.getResources().getString(...)nếu nó không có sẵn.
  • String.format() cũng sẽ định dạng một Chuỗi.
  • Các thuật ngữ 1$2$không cần phải được sử dụng theo thứ tự đó. Đó là, 2$có thể đến trước 1$. Điều này hữu ích khi quốc tế hóa một ứng dụng cho các ngôn ngữ sử dụng một trật tự từ khác.
  • Bạn có thể sử dụng một công cụ xác định định dạng như %1$snhiều lần trong xml nếu bạn muốn lặp lại nó.
  • Sử dụng %%để có được %nhân vật thực tế .
  • Để biết thêm chi tiết, hãy đọc hướng dẫn hữu ích sau: Mẹo nhanh về Android SDK: Định dạng chuỗi tài nguyên

125

Khi bạn muốn sử dụng một tham số từ tệp String.xml thực tế mà không sử dụng bất kỳ mã Java nào:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE resources [
  <!ENTITY appname "WhereDat">
  <!ENTITY author "Oded">
]>

<resources>
    <string name="app_name">&appname;</string>
    <string name="description">The &appname; app was created by &author;</string>
</resources>

Điều này không hoạt động trên các tệp tài nguyên, tức là các biến phải được sao chép vào mỗi tệp XML cần chúng.


Đó là một câu trả lời tốt trừ khi bạn có một tham số bên trong <! [CDATA [& param; ]]>
Hermann Poilpre

2
Có cách nào để xác định <!DOCTYPE... ]>phần trong một tệp riêng biệt và đưa nó vào nhiều tệp tài nguyên không? Bất kỳ mẹo để đạt được điều này?
prom85

18

Đã tìm kiếm tương tự và cuối cùng tìm thấy giải pháp rất đơn giản sau đây. Tốt nhất: nó hoạt động ra khỏi hộp.
1. thay đổi chuỗi nguồn của bạn:

<string name="welcome_messages">Hello, <xliff:g name="name">%s</xliff:g>! You have 
<xliff:g name="count">%d</xliff:g> new messages.</string>

2. sử dụng thay thế chuỗi:

c.getString(R.string.welcome_messages,name,count);

Trong đó c là Ngữ cảnh, tên là biến chuỗi và đếm biến int của bạn

Bạn sẽ cần phải bao gồm

<resources xmlns:xliff="http://schemas.android.com/apk/res-auto">

trong res / chuỗi.xml của bạn. Làm việc cho tôi. :)


2
Điểm của các xliffthẻ xung quanh các định dạng định dạng là gì? Những giá trị bổ sung nào họ thêm vào thay vì chỉ sử dụng %s%dchỉ định riêng?
Richard Le Mesurier

Thuộc tính "name" trong thẻ xliff chỉ là một cách để đưa ra gợi ý cho người dịch về những gì sẽ được thay thế trong đó. Đôi khi không dễ đoán "% s" nghĩa là gì.
hugomg

3

Trong Kotlin, bạn chỉ cần đặt giá trị chuỗi của mình như thế này:

<string name="song_number_and_title">"%1$d ~ %2$s"</string>

Tạo chế độ xem văn bản trên bố cục của bạn:

<TextView android:id="@+id/song_number_and_title"/>

Sau đó, làm điều này trong mã của bạn nếu bạn sử dụng Anko:

val song = database.use { // get your song from the database }
song_number_and_title.setText(resources.getString(R.string.song_number_and_title, song.number, song.title))  

Bạn có thể cần lấy tài nguyên của mình từ ngữ cảnh ứng dụng.


5
Điều đó khác với các ví dụ java như thế nào? Tôi thấy không có gì khác biệt
Janusz Hain


1

trong res / value / string.xml

<resources>
    <string name="app_name">Hello World</string>
    <string name="my_application">Application name: %s, package name: %s</string>
</resources>

trong mã java

String[] args = new String[2];
args[0] = context.getString(R.string.app_name);
args[1] = context.getPackageName();
String textMessage = context.getString(R.string.my_application,(Object[]) args);


1

Nếu bạn muốn viết phần trăm (%), sao chép nó:

<string name="percent">%1$d%%</string>

label.text = getString(R.string.percent, 75) // Output: 75%.

Nếu bạn viết đơn giản %1$d%, bạn sẽ nhận được lỗi : Format string 'percent' is not a valid format string so it should not be passed to String.format.


0

Đúng! bạn có thể làm như vậy mà không cần viết bất kỳ mã Java / Kotlin nào, chỉ XML bằng cách sử dụng thư viện nhỏ này mà tôi đã tạo, lúc này xây dựng nên ứng dụng của bạn sẽ không bị ảnh hưởng bởi nó: https://github.com/LikeTheSalad/android tham chiếu chuỗi

Sử dụng

Chuỗi của bạn:

<resources>
    <string name="app_name">My App Name</string>
    <string name="template_welcome_message">Welcome to ${app_name}</string>
</resources>

Chuỗi được tạo sau khi xây dựng:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>

0

Một giải pháp trực tiếp cho vấn đề:

chuỗi DOM

<string name="customer_message">Hello, %1$s!\nYou have %2$d Products in your cart.</string>

kotlinActivityORFragmentFile.kt:

val username = "Andrew"
val products = 1000
val text: String = String.format(
      resources.getString(R.string.customer_message), username, products )

0

Trong tệp chuỗi của bạn sử dụng này

<string name="redeem_point"> You currently have %s points(%s points = 1 %s)</string>

Và trong mã của bạn sử dụng cho phù hợp

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));

-1

Phiên bản Kotlin của câu trả lời được chấp nhận ...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)

3
Cách chính xác hơn là sử dụng resources.getString(int, ... args)phương thức với các đối số thay vì String.format. Không có chi tiết cụ thể về kotlin trong mã này, sau đó là valtừ khóa. Xem câu trả lời của msbodw001
dant3
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.