Apakah mungkin secara dinamis menambahkan String ke String.xml di Android?

Jawaban:

1035

Pemformatan dan Styling

Ya, lihat berikut ini dari Sumber Daya String: Memformat dan Styling

Jika Anda perlu memformat string Anda menggunakan String.format(String, Object...), maka Anda bisa melakukannya dengan meletakkan argumen format Anda di sumber daya string. Misalnya, dengan sumber daya berikut:

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

Dalam contoh ini, format string memiliki dua argumen: %1$sadalah string dan %2$dangka desimal. Anda dapat memformat string dengan argumen dari aplikasi Anda seperti ini:

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

Penggunaan Dasar

Catatan yang getStringmemiliki kelebihan yang menggunakan string sebagai string format:

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

Bentuk jamak

Jika Anda perlu menangani bentuk jamak, gunakan ini:

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

mailCountParam pertama digunakan untuk memutuskan format mana yang akan digunakan (tunggal atau jamak), params lainnya adalah substitusi Anda:

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

Lihat Sumber Daya String: bentuk jamak untuk lebih jelasnya.

Megha Joshi - GoogleTV DevRel
sumber
61
Panggilan String.format dalam sampel kode pertama sebenarnya tidak diperlukan, Resources.getString () mendukung pemformatan, lihat: developer.android.com/reference/android/content/res/… , java.lang.Object ...)
Arnaud
16
untuk bentuk jamak dalam String.xml Anda harus memberikan id sebagai R.plurals.welcome_messages, bukan R.string.welcome_messages
om252345
jamak hanya mengembalikan string item terakhir ... tahu bagaimana bisa mendapatkan menambahkan string.
CoDe
1
Saat menggunakan metode ini untuk memformat string Anda, itu menghapus meta tag yang mungkin Anda gunakan seperti hyperlink, dll. Yang mungkin terkandung dalam teks string xml
Jonathan
4
String adalah singkatan dari% 1 $ s, desimal untuk% 2 $ d dan integer artinya apa? apa artinya% 1,% 2.Apakah penghitungan parameter ini? .jika saya ingin parameter ketiga disebutkan% 3?
mulai lagi
260

Jawaban Tambahan

Ketika saya pertama kali melihat %1$sdan %2$ddalam jawaban yang diterima, itu tidak masuk akal. Ini sedikit penjelasan.

Mereka disebut penentu format. Dalam string xml mereka dalam bentuk

%[parameter_index$][format_type] 
  • % : Tanda persen menandai awal dari penentu format.
  • indeks parameter : Ini adalah angka yang diikuti oleh tanda dolar. Jika Anda memiliki tiga parameter yang Anda ingin memasukkan ke dalam string, maka mereka akan disebut 1$, 2$dan 3$. Urutan yang Anda tempatkan dalam string sumber daya tidak masalah, hanya urutan yang Anda berikan parameternya.
  • tipe format : Ada banyak cara Anda dapat memformat sesuatu ( lihat dokumentasi ). Berikut ini beberapa yang umum:

    • s tali
    • d bilangan bulat desimal
    • f angka titik mengambang

Contoh

Kami akan membuat string yang diformat berikut di mana bagian abu-abu dimasukkan secara terprogram.

Kakak saya Maryadalah 12tahun.

string.xml

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

Catatan

  • Saya bisa menggunakan getStringkarena saya sedang dalam suatu Kegiatan. Anda dapat menggunakan context.getResources().getString(...)jika tidak tersedia.
  • String.format() juga akan memformat String.
  • The 1$dan 2$istilah tidak perlu digunakan dalam urutan itu. Artinya, 2$bisa datang sebelumnya 1$. Ini berguna saat internasionalisasi aplikasi untuk bahasa yang menggunakan urutan kata yang berbeda.
  • Anda dapat menggunakan penentu format seperti %1$sbeberapa kali dalam xml jika Anda ingin mengulanginya.
  • Gunakan %%untuk mendapatkan %karakter yang sebenarnya .
  • Untuk lebih jelasnya baca tutorial bermanfaat berikut: Tip Cepat Android SDK: Memformat Resource Strings
Suragch
sumber
125

Saat Anda ingin menggunakan parameter dari file strings.xml aktual tanpa menggunakan kode Java apa pun:

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

Ini tidak berfungsi di file sumber, yaitu variabel harus disalin ke setiap file XML yang membutuhkannya.

Oded Breiner
sumber
Itu jawaban yang bagus kecuali ketika Anda memiliki parameter di dalam <! [CDATA [& param; ]]>
Hermann Poilpre
2
Apakah ada cara untuk mendefinisikan <!DOCTYPE... ]>bagian dalam file terpisah dan memasukkannya ke dalam beberapa file sumber daya? Adakah trik untuk mencapai ini?
prom85
18

Sedang mencari yang sama dan akhirnya menemukan solusi yang sangat sederhana berikut. Terbaik: ini bekerja di luar kotak.
1. ubah sumber daya string Anda:

<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. gunakan substitusi string:

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

di mana c adalah Konteks, nama adalah variabel string dan hitung variabel int Anda

Anda harus memasukkan

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

di res / strings.xml Anda. Bekerja untukku. :)

pengguna3016503
sumber
2
Apa gunanya xlifftag di sekitar penentu format? Nilai tambahan apa yang mereka tambahkan sebagai lawan dari hanya menggunakan %sdan %dpenspesifikasi sendiri?
Richard Le Mesurier
Atribut "name" di tag xliff hanyalah cara untuk memberi petunjuk kepada penerjemah tentang apa yang akan diganti di sana. Terkadang tidak mudah untuk menebak apa arti "% s".
hugomg
3

Di Kotlin Anda hanya perlu menetapkan nilai string Anda seperti ini:

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

Buat tampilan teks pada tata letak Anda:

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

Kemudian lakukan ini dalam kode Anda jika Anda menggunakan 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))  

Anda mungkin perlu mendapatkan sumber daya dari konteks aplikasi.

msbodw001
sumber
5
Bagaimana itu berbeda dari contoh java? Saya tidak melihat perbedaan
Janusz Hain
1

di res / values ​​/ string.xml

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

dalam kode 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);
Chanh
sumber
1

Jika Anda ingin menulis persen (%), duplikat:

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

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

Jika Anda menulis hanya %1$d%, Anda akan mendapatkan error: Format string 'percent' is not a valid format string so it should not be passed to String.format.

CoolMind
sumber
0

Iya! Anda dapat melakukannya tanpa menulis kode Java / Kotlin, hanya XML dengan menggunakan perpustakaan kecil yang saya buat ini, yang melakukannya saat buildtime, sehingga aplikasi Anda tidak akan terpengaruh olehnya: https://github.com/LikeTheSalad/android -string-referensi

Pemakaian

String Anda:

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

String yang dihasilkan setelah bangunan:

<!--resolved.xml-->
<resources>
    <string name="welcome_message">Welcome to My App Name</string>
</resources>
César Muñoz
sumber
0

Solusi Kotlin Langsung untuk masalah ini:

strings.xml

<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 )
nyxee
sumber
0

Dalam file string Anda gunakan ini

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

Dan dalam kode Anda gunakan sesuai

coinsTextTV.setText(String.format(getContext().getString(R.string.redeem_point), rewardPoints.getReward_points()
                        , rewardPoints.getConversion_rate(), getString(R.string.rs)));
Soni Kumar
sumber
-1

Versi Kotlin dari jawaban yang diterima ...

val res = resources
val text = String.format(res.getString(R.string.welcome_messages), username, mailCount)
jesses.co.tt
sumber
3
Cara yang lebih benar adalah dengan menggunakan resources.getString(int, ... args)metode dengan argumen, bukan String.format. Tidak ada spesifikasi kotlin dalam kode ini, selain valkata kunci. Lihat jawaban msbodw001
dant3