Dize kaynağı, uygulamanız için isteğe bağlı metin stili ve biçimlendirme içeren metin dizeleri sağlar. Uygulamanıza dizeler sağlayabilecek üç tür kaynak vardır:
- String
- Tek bir dize sağlayan XML kaynağı.
- Dize Dizisi (String Array)
- Dizi dizisi sağlayan XML kaynağı.
- Miktar Dizeleri (Çoğullar)
- Çoğul oluşturma için farklı dizeler içeren XML kaynağı.
Tüm dizeler, bazı stil işaretlemelerini ve biçimlendirme bağımsız değişkenlerini uygulayabilir. Dizeleri stil verme ve biçimlendirme hakkında bilgi edinmek için Biçimlendirme ve Stil Verme bölümüne bakın.
Dize
Uygulama kodundan (ör. composable işlevi) veya diğer kaynak dosyalarından referans verilebilen tek bir dize.
- Dosya konumu:
res/values/filename.xml
Dosya adı rastgeledir.<string>öğesininname, kaynak kimliği olarak kullanılır.- derlenmiş kaynak veri türü:
- ,
Stringöğesine yönelik kaynak işaretçisi. - kaynak referansı:
-
Kotlin'de:
R.string.string_name
XML'de:@string/string_name - söz dizimi:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
- öğeler:
- örnek:
- XML dosyası
res/values/strings.xmlkonumuna kaydedildi:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
Bu uygulama kodu,
stringResource()ile oluşturulabilen bir composable'ın içinden bir dize alır:@Composable fun Greeting() { Text(text = stringResource(R.string.hello)) }
Not: Bir composable işlevinin dışındaki bir dizeyi almak için
Ayrıca,context.getString(R.string.hello)kullanın.AndroidManifest.xmlgibi diğer XML dosyalarındaki dize kaynaklarına da referans verebilirsiniz:<activity android:name=".MainActivity" android:label="@string/hello" />
Dize dizisi
Uygulamadan referans verilebilecek bir dizeler dizisi.
- Dosya konumu:
res/values/filename.xml
Dosya adı rastgeledir.<string-array>öğesininname, kaynak kimliği olarak kullanılır.- derlenmiş kaynak veri türü:
Stringdizisine yönelik kaynak işaretçisi.- kaynak referansı:
-
Kotlin'de:
R.array.string_array_name
XML'de:@[package:]array/string_array_name - söz dizimi:
-
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
- öğeler:
- örnek:
- XML dosyası
res/values/strings.xmlkonumuna kaydedildi:<?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>
Bu uygulama kodu,
stringArrayResource()ile oluşturulabilen bir composable'ın içinden bir dize dizisi alır:@Composable fun PlanetList() { val planets: Array
= stringArrayResource(R.array.planets_array) // Render the array, e.g. inside a LazyColumn. } Not: Bir dize dizisini composable işlevin dışında almak için
context.resources.getStringArray(R.array.planets_array)kullanın.
Miktar dizeleri (çoğullar)
Farklı dillerde, miktarla ilgili dilbilgisi kuralları farklıdır. Örneğin, İngilizcede 1 sayısı özel bir durumdur. "1 kitap" yazıyoruz ancak diğer miktarlar için "n kitap" yazıyoruz. Tekil ve çoğul arasındaki bu ayrım çok yaygındır ancak diğer dillerde daha ince ayrımlar yapılır. Android tarafından desteklenen tam küme zero, one, two, few, many ve other şeklindedir.
Belirli bir dil ve miktar için hangi büyük/küçük harf durumunun kullanılacağına karar verme kuralları çok karmaşık olabilir. Bu nedenle Android, sizin için uygun kaynağı seçebilmeniz amacıyla pluralStringResource() gibi yöntemler sunar.
Geçmişte "miktar dizeleri" olarak adlandırılmış olsa da (API'de hâlâ bu şekilde adlandırılır) miktar dizeleri yalnızca çoğullar için kullanılmalıdır. Örneğin, okunmamış iletiler olduğunda Gmail'in "Gelen Kutusu" ile "Gelen Kutusu (12)" gibi bir özelliği uygulamak için miktar dizelerini kullanmak hatalı olur. if ifadesi yerine miktar dizeleri kullanmak kolaylık sağlayabilir ancak bazı dillerde (ör. Çince) bu gramer ayrımlarının hiç yapılmadığını ve bu nedenle her zaman other dizesini alacağınızı unutmayın.
Hangi dizenin kullanılacağı yalnızca dilbilgisi açısından gerekli olmasına göre belirlenir. İngilizcede, miktar 0 olsa bile zero dizesi yoksayılır. Bunun nedeni, 0'ın dilbilgisi açısından 2'den veya 1 dışındaki diğer sayılardan farklı olmamasıdır ("zero books", "one book", "two books" vb.). Buna karşılık, Korece'de other dizesi yalnızca kullanılır.
Örneğin, two ifadesinin yalnızca 2 miktarı için geçerli olabileceği yanılgısına düşmeyin. Bir dilde 2, 12, 102 vb. miktarlar birbirine benzer şekilde, diğer miktarlardan ise farklı şekilde ele alınabilir. Çevirmeninizin, dilinde hangi ayrımların yapılması gerektiğini bildiğinden emin olun.
İletinizde miktar sayısı yoksa büyük ihtimalle çoğul için uygun değildir. Örneğin, Litvanca'da hem 1 hem de 101 için tekil biçim kullanılır. Bu nedenle "1 kitap" ifadesi "1 knyga", "101 kitap" ifadesi ise "101 knyga" olarak çevrilir. Bu arada "a book" (bir kitap) "knyga", "many books" (birçok kitap) ise "daug knygų" olarak çevrilir. İngilizce bir çoğul mesajda "a book" (tekil) ve gerçek sayı olmadan "many books" (çoğul) varsa "knyga" (bir kitap)/"daug knygų" (çok kitap) olarak çevrilebilir ancak Litvanca kurallarına göre sayı 101 olduğunda "knyga" (tek bir kitap) gösterilir.
"Kitaplar: 1" gibi miktardan bağımsız ifadeler kullanarak genellikle miktar dizelerinden kaçınabilirsiniz. Bu, uygulamanız için kabul edilebilir bir stilse hem sizin hem de çevirmenlerinizin hayatını kolaylaştırır.
API 24 ve sonraki sürümlerde bunun yerine çok daha güçlü olan ICU MessageFormat sınıfını kullanabilirsiniz.
- Dosya konumu:
res/values/filename.xml
Dosya adı rastgeledir.<plurals>öğesininname, kaynak kimliği olarak kullanılır.- kaynak referansı:
-
Kotlin'de:
R.plurals.plural_name - söz dizimi:
-
<?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>
- öğeler:
- örnek:
XML dosyası
res/values/strings.xmlkonumuna kaydedildi:<?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>
XML dosyası
res/values-pl/strings.xmlkonumuna kaydedildi:<?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>
Bu uygulama kodu,
pluralStringResource()ile oluşturulabilen bir composable'ın içinden çoğul bir dizeyi alır:@Composable fun SongCount(count: Int) { Text( text = pluralStringResource( R.plurals.numberOfSongsAvailable, count, count, ) ) }
pluralStringResource()işlevini kullanırken dizenizde sayıyla birlikte dize biçimlendirmesi varsacountöğesini iki kez iletmeniz gerekir. Örneğin,%d songs founddizesi için ilkcountparametresi uygun çoğul dizesini seçer ve ikincicountparametresi%dyer tutucusuna eklenir. Çoğul dizeleriniz dize biçimlendirmesi içermiyorsa üçüncü parametreyipluralStringResource'ya iletmeniz gerekmez.Not: Bir composable işlevinin dışında çoğul dize almak için
context.resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count)kullanın.
Biçim ve stil
Dize kaynaklarınızı doğru şekilde biçimlendirme ve stil verme hakkında bilmeniz gereken birkaç önemli nokta aşağıda belirtilmiştir.
Özel karakterleri işleme
Bir dize, XML'de özel kullanımı olan karakterler içerdiğinde karakterleri standart XML/HTML kaçış kurallarına göre kaçırmanız gerekir. Android'de özel anlamı olan bir karakterden çıkmanız gerekiyorsa öncesinde ters eğik çizgi kullanmanız gerekir.
Android, varsayılan olarak boşluk karakteri dizilerini tek bir boşlukla daraltır. Dizenizin ilgili bölümünü çift tırnak içine alarak bu durumu önleyebilirsiniz. Bu durumda, yeni satırlar da dahil olmak üzere tüm boşluk karakterleri alıntılanan bölgede korunur. Çift tırnak işareti, normal tek tırnak işaretlerini de kullanmanıza olanak tanır.
| Karakter | Kaçırılan formlar |
|---|---|
| @ | \@ |
| ? | \? |
| Yeni satır | \n |
| Sekme | \t |
| U+XXXX Unicode karakteri | \uXXXX |
Tek tırnak işareti (') |
Aşağıdakilerden herhangi biri:
|
Çift tırnak işareti (") |
\"
Diziyi tek tırnak içine almanın işe yaramadığını unutmayın. |
Beyaz alan daraltma ve Android kaçış karakteri, kaynak dosyanız XML olarak ayrıştırıldıktan sonra gerçekleşir. Bu, dosya XML olarak ayrıştırıldıktan sonra tümü Unicode boşlukları olduğundan <string>      </string>
(boşluk, noktalama işareti boşluğu, Unicode Em boşluğu) karakterlerinin tümünün tek bir boşluk (" ") olarak daraltıldığı anlamına gelir.
Bu boşlukları olduğu gibi korumak için bunları alıntılayabilir (<string>"      "</string>) veya Android kaçış karakterini (<string> \u0032 \u8200 \u8195</string>) kullanabilirsiniz.
Biçimlendirme dizeleri
Dizelerinizi biçimlendirmeniz gerekiyorsa aşağıdaki örnek kaynakta gösterildiği gibi biçim bağımsız değişkenlerinizi dize kaynağına yerleştirerek bunu yapabilirsiniz.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
Bu uygulama kodu, bağımsız değişkenleri doğrudan stringResource() içine ileterek bir composable'ın içindeki dizeyi biçimlendirir:
@Composable fun WelcomeMessage(username: String, mailCount: Int) { Text( text = stringResource( R.string.welcome_messages, username, mailCount, ) ) }
HTML biçimlendirmesiyle stil oluşturma
HTML işaretlemesiyle dizelerinize stil ekleyebilirsiniz. Örneğin:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Aşağıdaki HTML öğeleri desteklenir:
- Kalın:
<b> - İtalik:
<i>,<cite>,<dfn>,<em> - %25 daha büyük metin:
<big> - %20 daha küçük metin:
<small> - Yazı tipi özelliklerini ayarlama:
<font face="font_family" color="hex_color">. Olası yazı tipi ailelerine örnek olarakmonospace,serifvesans_serifverilebilir. - Sabit genişlikli yazı tipi ailesi ayarlama:
<tt> - Üstü çizili:
<s>,<strike>,<del> - Altı çizili:
<u> - Üst simge:
<sup> - Alt simge:
<sub> - Madde işaretleri:
<ul>,<li> - Satır sonları:
<br> - İdari bölüm:
<div> - CSS stili:
<span style="color|background_color|text-decoration"> - Paragraflar:
<p dir="rtl | ltr" style="…">
Bazı durumlarda, biçim dizesi olarak da kullanılan stilize bir metin kaynağı oluşturmak isteyebilirsiniz. Normalde bu işlem çalışmaz. Çünkü stringResource() gibi biçimlendirme yöntemleri, dizedeki tüm stil bilgilerini kaldırır.
Bunun geçici çözümü, HTML etiketlerini kaçış karakteri eklenmiş öğelerle yazmaktır. Bu öğeler, biçimlendirme işlemi gerçekleştikten sonra AnnotatedString.fromHtml() ile kurtarılır. Örneğin:
- Stil verilmiş metin kaynağınızı HTML'den kaçışlı dize olarak depolayın:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
Bu biçimlendirilmiş dizeye bir
<b>öğesi eklenir. Açma parantezinin<gösterimi kullanılarak HTML'den kaçırıldığına dikkat edin. - Ardından dizeyi her zamanki gibi biçimlendirin ancak HTML metnini biçimlendirilmiş bir Compose dizesine dönüştürmek için
AnnotatedString.fromHtml()işlevini de çağırın.
fromHtml() tüm HTML öğelerini biçimlendirdiğinden, biçimlendirilmiş metinle kullandığınız dizelerdeki olası HTML karakterlerinden TextUtils.htmlEncode() kullanarak çıkış yaptığınızdan emin olun.
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) ) }
AnnotatedString ile stil oluşturma
AnnotatedString, renk ve yazı tipi ağırlığı gibi özelliklerle stil verebileceğiniz bir Compose metin nesnesidir. buildAnnotatedString ve withStyle kullanarak programatik olarak stilli metinler oluşturun.
Bu uygulama kodu, karışık stillere sahip tek bir metin öğesi oluşturur:
@Composable fun StyledGreeting() { val styled = buildAnnotatedString { append("Welcome to ") withStyle(SpanStyle(fontWeight = FontWeight.Bold)) { append("Android") } append("!") } Text(text = styled) }
Renk, yazı tipi boyutu ve metin süslemesi uygulamak için SpanStyle simgesini kullanın. Paragraf düzeyinde stil (ör. hizalama veya satır yüksekliği) uygulamak için ParagraphStyle simgesini kullanın:
@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) }
AnnotatedString öğesini doğrudan oluşturmak, Compose'daki tek dilli uygulamalar veya statik metinler için önerilen yaklaşımdır. Ancak yerelleştirme gerektiren stillendirilmiş metinler için sonraki bölümde ayrıntılı olarak açıklanan XML <annotation> yaklaşımına bakın.
Çevrilen dizeleri ek açıklamalarla biçimlendirme
Özel stil ve çeviri gerektiren dizeler için her yerel ayarın strings.xml bölümünde <annotation> etiketini tanımlayın. Çevirmenler, cümlenin neresinde olursa olsun ek açıklamayı korur. context.resources.getText() ile dizeyi okuyun, Annotation aralıklarını inceleyin ve sonucu AnnotatedString biçimine dönüştürün:
@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) }
XML'nizdeki <annotation> etiketi değişmez. Yalnızca alma kodu farklıdır. Çevirmenler, her dilde doğru kelimeyi sarmak için etiketi taşımaya devam eder.
Ek kaynaklar
Dize kaynakları hakkında daha fazla bilgi için aşağıdaki ek kaynaklara bakın: