Dize kaynakları

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> öğesinin name, 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:
<resources>
Zorunlu. Bu, kök düğüm olmalıdır.

Özellik yok.

<string>
Stil etiketleri içerebilen bir dize. Kesme işaretlerini ve tırnak işaretlerini kod dışına almanız gerektiğini unutmayın. Dizelerinizi nasıl doğru şekilde stilize edeceğiniz ve biçimlendireceğiniz hakkında daha fazla bilgi için aşağıdaki Biçimlendirme ve Stil bölümüne bakın.

özellikleri:

name
String. Dizenin adı. Bu ad, kaynak kimliği olarak kullanılır.
örnek:
XML dosyası res/values/strings.xml konumuna 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 context.getString(R.string.hello) kullanın.

Ayrıca, AndroidManifest.xml gibi 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> öğesinin name, kaynak kimliği olarak kullanılır.
derlenmiş kaynak veri türü:
String dizisine 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:
<resources>
Zorunlu. Bu, kök düğüm olmalıdır.

Özellik yok.

<string-array>
Dize dizisini tanımlar. Bir veya daha fazla <item> öğesi içerir.

özellikleri:

name
String. Dizinin adı. Bu ad, diziye referans vermek için kaynak kimliği olarak kullanılır.
<item>
Stil etiketleri içerebilen bir dize. Değer, başka bir dize kaynağına referans olabilir. <string-array> öğesinin alt öğesi olmalıdır. Kesme işaretlerinin ve tırnak işaretlerinin kod dışı bırakılması gerektiğini unutmayın. Dizelerinizi doğru şekilde biçimlendirme ve stil verme hakkında bilgi edinmek için aşağıdaki Biçimlendirme ve Stil Verme bölümüne bakın.

Özellik yok.

örnek:
XML dosyası res/values/strings.xml konumuna 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> öğesinin name, 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:
<resources>
Zorunlu. Bu, kök düğüm olmalıdır.

Özellik yok.

<plurals>
Bir şeyin miktarına bağlı olarak sağlanan dizelerden oluşan bir koleksiyon. Bir veya daha fazla <item> öğesi içerir.

özellikleri:

name
String. Dize çiftinin adı. Bu ad, kaynak kimliği olarak kullanılır.
<item>
Çoğul veya tekil bir dize. Değer, başka bir dize kaynağına referans olabilir. <plurals> öğesinin alt öğesi olmalıdır. Kesme işaretlerinden ve tırnak işaretlerinden kaçınmanız gerektiğini unutmayın. Dizelerinizi doğru şekilde stilize etme ve biçimlendirme hakkında bilgi edinmek için aşağıdaki Biçimlendirme ve Stil bölümüne bakın.

özellikleri:

quantity
Anahtar kelime. Bu dizenin ne zaman kullanılması gerektiğini belirten bir değer. Geçerli değerler (parantez içinde olası her duruma yer verilmeyen örnekler):
DeğerAçıklama
zeroDil, 0 sayısının özel olarak ele alınmasını gerektirdiğinde (ör. Arapça).
oneDil, sayıların özel bir şekilde ele alınmasını gerektirdiğinde (ör. İngilizce ve çoğu dilde 1 sayısı; Rusçada 11 ile bitmeyen ancak 1 ile biten tüm sayılar bu sınıftadır).
twoDil, sayılara özel işlem yapılmasını gerektirdiğinde (ör. Galce'de 2, Slovence'de 102).
fewDil, "küçük" sayıların özel işlem görmesini gerektirdiğinde (ör. Çekçe'de 2, 3 ve 4; Lehçe'de 2, 3 veya 4 ile biten ancak 12, 13 veya 14 ile bitmeyen sayılar).
manyDil, "büyük" sayıların özel olarak işlenmesini gerektirdiğinde (ör. Maltaca'da 11-99 ile biten sayılar).
otherDil, verilen miktarın özel olarak ele alınmasını gerektirmediğinde (ör. Çince'deki tüm sayılar veya İngilizce'deki 42 sayısı).
örnek:

XML dosyası res/values/strings.xml konumuna 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.xml konumuna 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 varsa count öğesini iki kez iletmeniz gerekir. Örneğin, %d songs found dizesi için ilk count parametresi uygun çoğul dizesini seçer ve ikinci count parametresi %d yer tutucusuna eklenir. Çoğul dizeleriniz dize biçimlendirmesi içermiyorsa üçüncü parametreyi pluralStringResource'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:

  • \'
  • Dizenin tamamını çift tırnak içine alın (örneğin, "This'll work")
Ç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> &#32; &#8200; &#8195;</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>" &#32; &#8200; &#8195;"</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 olarak monospace, serif ve sans_serif verilebilir.
  • 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:

  1. Stil verilmiş metin kaynağınızı HTML'den kaçışlı dize olarak depolayın:
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>

    Bu biçimlendirilmiş dizeye bir <b> öğesi eklenir. Açma parantezinin &lt; gösterimi kullanılarak HTML'den kaçırıldığına dikkat edin.

  2. 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:

Belgeler

İçeriği görüntüleme