Resource string menyediakan string teks untuk aplikasi Anda dengan pemformatan dan penataan gaya teks opsional. Ada tiga jenis resource yang bisa menyediakan string untuk aplikasi Anda:
- String
- Resource XML yang menyediakan string tunggal.
- String Array
- Resource XML yang menyediakan array string.
- String Jumlah (Jamak)
- Resource XML yang membawa string berbeda untuk pluralisasi.
Semua string mampu menerapkan beberapa argumen markup penataan gaya dan pemformatan. Untuk informasi tentang string penataan gaya dan pemformatan, lihat bagian tentang Pemformatan dan Penataan Gaya.
String
String tunggal yang dapat direferensikan dari kode aplikasi (seperti fungsi composable) atau dari file resource lainnya.
- lokasi file:
res/values/filename.xml
Nama file bersifat arbitrer.nameelemen<string>digunakan sebagai ID resource.- jenis data resource yang dihimpun:
- Pointer resource ke
String. - referensi resource:
-
Di Kotlin:
R.string.string_name
Dalam XML:@string/string_name - sintaksis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
- elemen:
- contoh:
- File XML yang disimpan di
res/values/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
Kode aplikasi ini mengambil string dari dalam composable dengan
stringResource():@Composable fun Greeting() { Text(text = stringResource(R.string.hello)) }
Catatan: Untuk mengambil string di luar fungsi composable, gunakan
Anda juga dapat mereferensikan resource string dari file XML lain, seperticontext.getString(R.string.hello).AndroidManifest.xml:<activity android:name=".MainActivity" android:label="@string/hello" />
Array string
Array string yang bisa direferensikan dari aplikasi.
- lokasi file:
res/values/filename.xml
Nama file bersifat arbitrer.nameelemen<string-array>digunakan sebagai ID resource.- jenis data resource yang dihimpun:
- Pointer resource ke array
String. - referensi resource:
-
Di Kotlin:
R.array.string_array_name
Dalam XML:@[package:]array/string_array_name - sintaksis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
- elemen:
- contoh:
- File XML yang disimpan di
res/values/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="planets_array"> <item>Mercury</item> <item>Venus</item> <item>Earth</item> <item>Mars</item> </string-array> </resources>
Kode aplikasi ini mengambil array string dari dalam composable dengan
stringArrayResource():@Composable fun PlanetList() { val planets: Array
= stringArrayResource(R.array.planets_array) // Render the array, e.g. inside a LazyColumn. } Catatan: Untuk mengambil array string di luar fungsi composable, gunakan
context.resources.getStringArray(R.array.planets_array).
String jumlah (jamak)
Bahasa yang berbeda memiliki aturan yang berbeda pula untuk kesepakatan gramatikal pada jumlah. Dalam bahasa Inggris, misalnya, jumlah 1 adalah kasus khusus. Kita menulis
"1 buku", tetapi untuk jumlah lain kita akan menulis "n buku". Perbedaan antara tunggal dan jamak sudah sangat umum, tetapi bahasa lain membuat perbedaan yang lebih tipis. Set lengkap yang didukung Android adalah zero, one, two, few,
many, dan other.
Aturan untuk memutuskan kasus mana yang akan digunakan untuk bahasa dan jumlah yang diberikan boleh jadi akan sangat kompleks, jadi Android menyediakan beberapa metode seperti pluralStringResource() untuk memilih resource yang sesuai untuk Anda.
Meskipun secara historis disebut "string jumlah" (dan tetap disebut demikian di API),
string jumlah hanya boleh digunakan untuk jamak. Akan salah jika
menggunakan string jumlah untuk mengimplementasikan sesuatu seperti "Kotak Masuk" Gmail dan
"Kotak Masuk (12)" saat ada pesan yang belum dibaca. Sepertinya mungkin praktis menggunakan string jumlah sebagai ganti pernyataan if, tetapi perlu diperhatikan bahwa beberapa bahasa (seperti bahasa China) tidak membuat perbedaan gramatikal ini sama sekali, jadi Anda akan selalu mendapatkan string other.
Pemilihan string yang akan digunakan dilakukan semata-mata berdasarkan keperluan gramatikal. Dalam bahasa Inggris, string untuk zero diabaikan meskipun jumlahnya
0, karena 0 secara gramatikal tidak berbeda dengan 2, atau angka lain kecuali 1
("zero books", "one book", "two books", dan seterusnya). Sebaliknya, dalam bahasa Korea
hanya string other yang pernah digunakan.
Jangan salah paham dengan fakta bahwa, misalnya, two seolah hanya bisa diterapkan pada
jumlah 2: suatu bahasa mungkin mengharuskan 2, 12, 102 (dan seterusnya) semua diperlakukan seperti satu sama lain, tetapi secara berbeda untuk jumlah lainnya. Percayakan pada penerjemah Anda untuk mengetahui perbedaan sesungguhnya dalam bahasa masing-masing.
Jika pesan Anda tidak berisi jumlah, itu mungkin bukan kandidat yang baik untuk jamak. Misalnya, dalam bahasa Lituania, bentuk tunggal digunakan untuk 1 dan 101, sehingga "1 buku" diterjemahkan sebagai "1 knyga", dan "101 buku" diterjemahkan sebagai "101 knyga". Sementara itu, "buku" adalah "knyga" dan "banyak buku" adalah "daug knygų". Jika pesan jamak dalam bahasa Inggris berisi "a book" (tunggal) dan "many books" (jamak) tanpa angka sebenarnya, pesan tersebut dapat diterjemahkan sebagai "knyga" (satu buku)/"daug knygų" (banyak buku), tetapi dengan aturan bahasa Lituania, pesan tersebut akan menampilkan "knyga" (satu buku), jika angkanya adalah 101.
Sering kali, string jumlah dapat dihindari dengan menggunakan formulasi netral jumlah seperti "Buku: 1". Hal ini membuat urusan Anda dan penerjemah Anda jadi lebih mudah, jika ini adalah gaya yang bisa diterima untuk aplikasi Anda.
Di API 24+, Anda dapat menggunakan class MessageFormat
ICU yang jauh lebih canggih.
- lokasi file:
res/values/filename.xml
Nama file bersifat arbitrer.nameelemen<plurals>digunakan sebagai ID resource.- referensi resource:
-
Di Kotlin:
R.plurals.plural_name - sintaksis:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="plural_name"> <item quantity=["zero" | "one" | "two" | "few" | "many" | "other"] >text_string</item> </plurals> </resources>
- elemen:
- contoh:
File XML yang disimpan di
res/values/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <!-- As a developer, you should always supply "one" and "other" strings. Your translators will know which strings are actually needed for their language. Always include %d in "one" because translators will need to use %d for languages where "one" doesn't mean 1 (as explained above). --> <item quantity="one">%d song found.</item> <item quantity="other">%d songs found.</item> </plurals> </resources>
File XML yang disimpan di
res/values-pl/strings.xml:<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">Znaleziono %d piosenkę.</item> <item quantity="few">Znaleziono %d piosenki.</item> <item quantity="other">Znaleziono %d piosenek.</item> </plurals> </resources>
Kode aplikasi ini mengambil string jamak dari dalam composable dengan
pluralStringResource():@Composable fun SongCount(count: Int) { Text( text = pluralStringResource( R.plurals.numberOfSongsAvailable, count, count, ) ) }
Saat menggunakan fungsi
pluralStringResource(), Anda perlu meneruskancountdua kali jika string berisi pemformatan string dengan angka. Misalnya, untuk string%d songs found, parametercountpertama akan memilih string jamak yang sesuai dan parametercountkedua akan dimasukkan ke dalam placeholder%d. Jika string jamak Anda tidak berisi pemformatan string, Anda tidak perlu meneruskan parameter ketiga kepluralStringResource.Catatan: Untuk mengambil string jamak di luar fungsi composable, gunakan
context.resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count).
Format dan gaya
Inilah beberapa hal penting yang harus Anda ketahui tentang cara yang benar untuk memformat dan menata gaya resource string.
Menangani karakter khusus
Jika string berisi karakter yang memiliki penggunaan khusus dalam XML, Anda harus meng-escape karakter sesuai dengan aturan escaping XML/HTML standar. Jika Anda perlu meng-escape karakter yang memiliki arti khusus di Android, Anda harus menggunakan garis miring terbalik sebelumnya.
Secara default, Android akan menciutkan urutan karakter spasi kosong menjadi satu spasi. Anda dapat menghindari hal ini dengan mengapit bagian string yang relevan dalam tanda kutip ganda. Dalam hal ini, semua karakter spasi kosong (termasuk baris baru) akan dipertahankan dalam region yang dikutip. Tanda kutip ganda juga akan memungkinkan Anda menggunakan tanda kutip tunggal tanpa konversi reguler.
| Karakter | Bentuk yang di-escape |
|---|---|
| @ | \@ |
| ? | \? |
| Baris baru | \n |
| Tab | \t |
| Karakter Unicode U+XXXX | \uXXXX |
Tanda petik tunggal (') |
Salah satu dari berikut:
|
Tanda kutip ganda (") |
\"
Perlu diperhatikan bahwa mengelilingi string dengan tanda kutip tunggal tidak berfungsi. |
Spasi kosong diciutkan dan escaping Android terjadi setelah file resource
Anda diurai sebagai XML. Artinya, <string>      </string>
(spasi, spasi tanda baca, spasi Unicode Em) semuanya diciutkan ke satu spasi
(" "), karena semuanya merupakan spasi Unicode setelah file diuraikan sebagai XML.
Untuk mempertahankan ruang tersebut apa adanya, Anda dapat mengutipnya
(<string>"      "</string>)
atau menggunakan escape Android
(<string> \u0032 \u8200 \u8195</string>).
Memformat string
Jika perlu memformat string, Anda dapat melakukannya dengan menempatkan argumen format dalam resource string, seperti yang ditunjukkan oleh resource contoh berikut.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Kode aplikasi ini memformat string dari dalam composable dengan meneruskan
argumen langsung ke stringResource():
@Composable fun WelcomeMessage(username: String, mailCount: Int) { Text( text = stringResource( R.string.welcome_messages, username, mailCount, ) ) }
Menata gaya dengan markup HTML
Anda bisa menambahkan penataan gaya ke string dengan markup HTML. Misalnya:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Elemen HTML berikut didukung:
- Tebal:
<b> - Miring:
<i>,<cite>,<dfn>,<em> - Teks 25% lebih besar:
<big> - 20% teks lebih kecil:
<small> - Menetapkan properti font:
<font face="font_family" color="hex_color">. Contoh kemungkinan jenis font meliputimonospace,serif, dansans_serif. - Menyetel jenis font monospace:
<tt> - Coret:
<s>,<strike>,<del> - Garis bawah:
<u> - Superskrip:
<sup> - Subskrip:
<sub> - Poin butir:
<ul>,<li> - Jeda baris:
<br> - Divisi:
<div> - Gaya CSS:
<span style="color|background_color|text-decoration"> - Paragraf:
<p dir="rtl | ltr" style="…">
Dalam beberapa kasus, Anda mungkin ingin membuat resource teks bergaya yang juga digunakan
sebagai string format. Biasanya, hal ini tidak akan berhasil karena metode pemformatan, seperti stringResource(), akan menghapus semua informasi gaya dari string.
Solusinya adalah menuliskan tag HTML dengan entitas yang dikurung, yang kemudian dipulihkan dengan AnnotatedString.fromHtml(), setelah pemformatan dilakukan. Contoh:
- Simpan resource teks bergaya sebagai string yang dikurung dengan HTML:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
Dalam string yang diformat ini, elemen
<b>telah ditambahkan. Perhatikan bahwa kurung buka adalah HTML yang di-escape, dengan menggunakan notasi<. - Kemudian format string tersebut seperti biasa, namun panggil juga
AnnotatedString.fromHtml()untuk mengonversi teks HTML menjadi string Compose yang diberi gaya.
Karena fromHtml() memformat semua entity HTML, pastikan untuk meng-escape semua karakter HTML yang memungkinkan dalam string yang Anda gunakan bersama teks berformat, menggunakan TextUtils.htmlEncode().
import android.text.TextUtils import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.fromHtml @Composable fun WelcomeHtmlMessage(username: String, mailCount: Int) { // Escape the username in case it contains characters like "<" or "&" val escapedUsername = TextUtils.htmlEncode(username) val text = stringResource( R.string.welcome_messages, escapedUsername, mailCount, ) Text( text = AnnotatedString.fromHtml(text) ) }
Menata gaya dengan AnnotatedString
AnnotatedString adalah objek teks Compose yang dapat Anda beri gaya dengan
properti seperti warna dan ketebalan font. Buat teks bergaya secara terprogram
menggunakan buildAnnotatedString dan withStyle.
Kode aplikasi ini membuat satu elemen teks dengan gaya campuran:
@Composable fun StyledGreeting() { val styled = buildAnnotatedString { append("Welcome to ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Android") } append("!") } Text(text = styled) }
Untuk menerapkan warna, ukuran font, dan dekorasi teks, gunakan SpanStyle. Untuk menerapkan
gaya tingkat paragraf (seperti perataan atau tinggi baris), gunakan ParagraphStyle:
@Composable fun RichText() { val text = buildAnnotatedString { withStyle(ParagraphStyle(lineHeight = 24.sp, textAlign = TextAlign.Center)) { withStyle(SpanStyle(color = Color.Gray)) { append("Hello, ") } withStyle( SpanStyle( fontWeight = FontWeight.Bold, color = Color.Red, ) ) { append("world") } append("!") } } Text(text = text) }
Membangun AnnotatedString secara langsung adalah pendekatan yang direkomendasikan untuk
aplikasi satu bahasa atau teks statis di Compose. Namun, untuk teks bergaya yang memerlukan pelokalan, lihat pendekatan <annotation> XML yang dijelaskan di bagian berikutnya.
Menata gaya string yang diterjemahkan dengan anotasi
Untuk string yang memerlukan gaya dan terjemahan kustom, tentukan tag
<annotation> di strings.xml setiap lokalitas. Penerjemah mempertahankan
anotasi, di mana pun posisinya dalam kalimat. Baca string dengan
context.resources.getText(), telusuri rentang Annotation-nya, dan konversi
hasilnya menjadi AnnotatedString:
@Composable fun AnnotatedTitle() { val context = LocalContext.current val source = context.resources.getText(R.string.title) as SpannedString val text = buildAnnotatedString { append(source.toString()) source.getSpans(0, source.length, Annotation::class.java) .forEach { annotation -> if (annotation.key == "font" && annotation.value == "title_emphasis") { addStyle( SpanStyle( fontFamily = FontFamily( Font(R.font.permanent_marker) ) ), source.getSpanStart(annotation), source.getSpanEnd(annotation), ) } } } Text(text = text) }
Tag <annotation> di XML Anda tidak berubah. Hanya kode pengambilan yang berbeda. Penerjemah tetap memindahkan tag untuk membungkus kata yang benar dalam setiap bahasa.
Referensi lainnya
Untuk mengetahui informasi selengkapnya tentang resource string, lihat referensi tambahan berikut: