Risorse stringa

Una risorsa stringa fornisce stringhe di testo per la tua applicazione con stili e formattazione del testo facoltativi. Esistono tre tipi di risorse che possono fornire la tua applicazione con stringhe:

String
Risorsa XML che fornisce una singola stringa.
Array di stringhe
Risorsa XML che fornisce un array di stringhe.
Stringhe di quantità (plurali)
Risorsa XML che trasporta diverse stringhe per la pluralizzazione.

Tutte le stringhe sono in grado di applicare alcuni markup di stile e argomenti di formattazione. Per per informazioni su stile e formattazione delle stringhe, consulta la sezione Formattazione e stili.

Stringa

Una singola stringa a cui si può fare riferimento dall'applicazione o da altri file di risorse (come come layout XML).

Nota: una stringa è una risorsa semplice a cui viene fatto riferimento utilizzando il valore fornito nell'attributo name (non il nome del file XML). Puoi quindi combinare risorse stringa con altre semplici risorse in un unico file XML, sotto un solo elemento <resources>.

percorso del file:

res/values/filename.xml
Il nome file è arbitrario. L'elemento name dell'elemento <string> viene utilizzato come dell'ID risorsa.
tipo di dati della risorsa compilato:
Puntatore della risorsa a String.
riferimento della risorsa:
In Java: R.string.string_name
In XML:@string/string_name
sintassi:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string
        name="string_name"
        >text_string</string>
</resources>
elementi:
<resources>
Obbligatorio. Deve essere il nodo radice.

Nessun attributo.

<string>
Una stringa che può includere tag di stile. Fai attenzione a evitare apostrofi e le virgolette. Per scoprire di più su come applicare e formattare correttamente le stringhe, consulta la sezione Formattazione e stili di seguito.

attributi:

name
Stringa. Un nome per la stringa. Questo nome viene utilizzato come risorsa ID.
esempio:
File XML salvato alle ore res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>

Questo XML di layout applica una stringa a una vista:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello" />

Questo codice dell'applicazione recupera una stringa:

Kotlin

val string: String = getString(R.string.hello)

Java

String string = getString(R.string.hello);

Puoi utilizzare getString(int) o getText(int) per recuperare una stringa. getText(int) conserva gli stili RTF applicati alla stringa.

Array di stringhe

Un array di stringhe a cui si può fare riferimento dall'applicazione.

Nota: un array di stringhe è una risorsa semplice a cui viene fatto riferimento utilizzando il valore fornito nell'attributo name (non il nome del file XML). Come Ad esempio, puoi combinare risorse di tipo array di stringhe con altre risorse semplici in un unico file XML, sotto un solo elemento <resources>.

percorso del file:

res/values/filename.xml
Il nome file è arbitrario. L'elemento name dell'elemento <string-array> viene utilizzato come dell'ID risorsa.
tipo di dati della risorsa compilato:
Puntatore della risorsa a un array di String.
riferimento della risorsa:
In Java: R.array.string_array_name
In XML: @[package:]array/string_array_name
sintassi:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
        name="string_array_name">
        <item
            >text_string</item>
    </string-array>
</resources>
elementi:
<resources>
Obbligatorio. Deve essere il nodo radice.

Nessun attributo.

<string-array>
Definisce un array di stringhe. Contiene uno o più elementi <item>.

attributi:

name
Stringa. Un nome per l'array. Questo nome viene utilizzato come risorsa per fare riferimento all'array.
<item>
Una stringa che può includere tag di stile. Il valore può essere un riferimento a un altro della stringa. Deve essere un elemento secondario di un elemento <string-array>. Fai attenzione a devono scappare da apostrofi le virgolette. Consulta la sezione Formattazione e stile, di seguito, per informazioni per lo stile e la formattazione delle stringhe.

Nessun attributo.

esempio:
File XML salvato alle ore 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>

Questo codice dell'applicazione recupera un array di stringhe:

Kotlin

val array: Array<String> = resources.getStringArray(R.array.planets_array)

Java

Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array);

Stringhe quantità (plurale)

Lingue diverse hanno regole diverse per l'accordo grammaticale con la quantità. In inglese, Ad esempio, la quantità 1 è un caso speciale. Scriviamo "1 libro", ma per qualsiasi altra quantità che scrivi "n libri". Questa distinzione tra singolare e plurale è molto comune, ma altra le lingue fanno distinzioni più fini. Il set completo supportato da Android è zero, one, two, few, many e other.

Le regole per decidere quale caso utilizzare per una data lingua e quantità possono essere molto complesse, Android ti offre quindi metodi come getQuantityString() per selezionare la risorsa più adatta a te.

Anche se storicamente si chiamavano "stringhe di quantità", (chiamato ancora in API), la quantità le stringhe devono essere utilizzate solo per le forme plurali. Sarebbe un errore usare le stringhe di quantità implementare qualcosa come "Posta in arrivo" di Gmail e "Posta in arrivo (12)" quando ci sono messaggi da leggere, ad esempio. Potrebbe sembrare pratico utilizzare stringhe di quantità anziché un'istruzione if, ma è importante notare che alcune lingue (come il cinese) non rendono grammaticali distinzioni, quindi avrai sempre la stringa other.

La selezione della stringa da utilizzare è stata effettuata esclusivamente in base alla necessità grammaticale. In inglese, una stringa per zero viene ignorata anche se la quantità è 0, perché 0 non è grammaticalmente diverso da 2 o da qualsiasi altro numero che non sia 1 ("zero libri", "un libro", "due libri" e così via). Al contrario, in coreano solo la stringa other è mai usata.

Non farti ingannare dal fatto che, ad esempio, two possa applicarsi solo a la quantità 2: una lingua può richiedere che 2, 12, 102 (e così via) siano tutti trattati come uno un'altra, ma in modo diverso rispetto ad altre quantità. Affidati al tuo traduttore per conoscere le distinzioni la loro lingua insiste.

Se il tuo messaggio non contiene il numero di quantità, probabilmente non è adatto per al plurale. Ad esempio, in lituano la forma singolare è usata sia per 1 che per 101, quindi "1 libro" sono tradotto come "1 knyga" e "101 libri" è tradotto come "101 knyga". Nel frattempo "un libro" è "knyga" e "molti libri" è "daug knygù". Se un messaggio plurale in inglese contiene "un libro" (singolare) e "molti libri" (plurale) senza il numero effettivo, può essere tradotto come "knyga" (un libro)/"daug knygai" (molti libri), ma con Secondo le regole in Lituania, verrà visualizzato "knyga" (un singolo libro), quando il numero è 101.

Spesso è possibile evitare le stringhe di quantità utilizzando formulazioni neutre come "Libri: 1". Questo rende la tua vita e i tuoi traduttori semplifica la vita, se è uno stile accettabile per la tua applicazione.

Nell'API 24 e versioni successive puoi usare l'ICU molto più potente MessageFormat .

Nota: una raccolta di plurali è una risorsa semplice che viene fatto riferimento utilizzando il valore fornito nell'attributo name (non il nome del file XML ). Di conseguenza, puoi combinare le risorse plurali con altre risorse semplici in un File XML, sotto un solo elemento <resources>.

percorso del file:

res/values/filename.xml
Il nome file è arbitrario. L'elemento name dell'elemento <plurals> viene utilizzato come dell'ID risorsa.
riferimento della risorsa:
In Java: R.plurals.plural_name
sintassi:
<?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>
elementi:
<resources>
Obbligatorio. Deve essere il nodo radice.

Nessun attributo.

<plurals>
Una raccolta di stringhe, di cui viene fornita una stringa in base alla quantità di qualcosa. Contiene uno o più elementi <item>.

attributi:

name
Stringa. Un nome per la coppia di stringhe. Questo nome viene utilizzato come dell'ID risorsa.
<item>
Una stringa singolare o plurale. Il valore può essere un riferimento a un altro della stringa. Deve essere un elemento secondario di un elemento <plurals>. Ricorda che devi escape apostrofi e virgolette. Consulta la sezione Formattazione e Stile, di seguito, per informazioni su come applicare uno stile e una formattazione corretti alle stringhe.

attributi:

quantity
Parola chiave. Un valore che indica quando deve essere utilizzata la stringa. Valido valori non esaustivi, con esempi non esaustivi tra parentesi:
ValoreDescrizione
zeroQuando la lingua richiede un trattamento speciale per il numero 0 (ad esempio, in arabo).
oneQuando la lingua richiede un trattamento speciale di numeri come uno (come il numero 1 in inglese e la maggior parte delle altre lingue; in russo, qualsiasi numero che termina con 1 ma non termina con 11 è in questa classe).
twoQuando la lingua richiede un trattamento speciale di numeri come due (come con 2 in gallese o 102 in sloveno).
fewQuando il linguaggio richiede un trattamento speciale del "piccolo" numeri (come con 2, 3 e 4 in ceco; o numeri che terminano 2, 3 o 4 ma non 12, 13 o 14 in polacco).
manyQuando il linguaggio richiede un trattamento speciale per il termine "grandi" numeri (come i numeri che terminano 11-99 in maltese).
otherQuando la lingua non richiede un trattamento speciale della quantità specificata (come per tutti i numeri in cinese o 42 in inglese).
esempio:
File XML salvato alle ore 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 salvato in 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>

Uso:

Kotlin

val count = getNumberOfSongsAvailable()
val songsFound = resources.getQuantityString(R.plurals.numberOfSongsAvailable, count, count)

Java

int count = getNumberOfSongsAvailable();
Resources res = getResources();
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);

Quando utilizzi il metodo getQuantityString(), devi passare count due volte se la stringa include formattazione stringa con un numero. Ad esempio, per la stringa %d songs found, il primo parametro count seleziona la stringa plurale appropriata e il secondo parametro count viene inserito nel segnaposto %d. Se la forma plurale le stringhe non includono la formattazione di stringa, non è necessario passare il terzo parametro a getQuantityString.

Formato e stile

Di seguito sono riportate alcune cose importanti che devi sapere su come formattare e definire lo stile delle risorse stringa.

Gestire i caratteri speciali

Quando una stringa contiene caratteri che vengono utilizzati in modo speciale in XML, devi eseguire l'interpretazione letterale del valore in base alle regole di escape standard XML/HTML. Se devi inserire il carattere di escape che ha un significato speciale in Android, devi prima utilizzare una barra rovesciata.

Per impostazione predefinita, Android comprime le sequenze di caratteri di spaziatura in un unico spazio. Puoi evitare che ciò accada racchiudendo la parte pertinente della stringa tra virgolette doppie. In questo caso tutti gli spazi vuoti (incluse le nuove righe) verranno conservati all'interno della regione tra virgolette. Le virgolette doppie consentono di utilizzare anche le virgolette singole e regolari senza caratteri di escape.

Carattere Moduli con caratteri di escape
@ \@
? \?
Nuova riga \n
Tab \t
U+XXXX carattere Unicode \uXXXX
Virgoletta singola (')

Uno dei seguenti:

  • \'
  • Racchiudi l'intera stringa tra virgolette doppie ("This'll work", ad esempio)
Virgolette doppie (") \"

Tieni presente che non è possibile racchiudere la stringa tra virgolette singole.

Gli spazi vuoti vengono compressi e l'escape di Android avviene dopo che del file di risorse viene analizzato come XML. Ciò significa che <string> &#32; &#8200; &#8195;</string> (spazio, spazio di punteggiatura, spazio Unicode Em) tutti vengono compressi in un unico spazio (" "), perché sono tutti spazi Unicode dopo che il file è stato analizzato come XML. Per mantenere gli spazi così come sono, puoi citarli (<string>" &#32; &#8200; &#8195;"</string>) o utilizzare caratteri di escape Android (<string> \u0032 \u8200 \u8195</string>).

Nota: dal punto di vista dell'analizzatore sintattico XML, non c'è differenza tra <string>"Test this"</string> e <string>&quot;Test this&quot;</string> di qualunque tipo. Entrambi i moduli non mostrerà virgolette, ma attiverà le citazioni Android che preservano lo spazio vuoto (che non avranno effetto pratico in questo caso).

Formattazione delle stringhe

Se devi formattare le stringhe, puoi farlo inserendo gli argomenti del formato nella risorsa stringa, come dimostrato dalla risorsa di esempio che segue.

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

In questo esempio, la stringa di formato ha due argomenti: %1$s è una stringa e %2$d è un numero decimale. Quindi, formatta la stringa richiamando getString(int, Object...). Ad esempio:

Kotlin

var text = getString(R.string.welcome_messages, username, mailCount)

Java

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

Stili con il markup HTML

Puoi aggiungere stili alle tue stringhe con il markup HTML. Ad esempio:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="welcome">Welcome to <b>Android</b>!</string>
</resources>

Sono supportati i seguenti elementi HTML:

  • Grassetto: <b>
  • Corsivo: <i>, <cite>, <nowrap>, <em>
  • Testo più grande del 25%: <big>
  • 20% di testo più piccolo: <small>
  • Impostazione delle proprietà del carattere: <font face=”font_family“ color=”hex_color”>. Esempi di le possibili famiglie di caratteri includono monospace, serif e sans_serif.
  • Impostazione di una famiglia di caratteri monospazio: <tt>
  • Barrato: <s>, <strike>, <del>
  • Sottolineato: <u>
  • Apice: <sup>
  • Pedice: <sub>
  • Elenchi puntati: <ul>, <li>
  • Interruzioni di riga: <br>
  • Divisione: <div>
  • Stile CSS: <span style=”color|background_color|text-decoration”>
  • Paragrafi: <p dir=”rtl | ltr” style=”...”>

Se non applichi la formattazione, puoi impostare il testo in Visualizzazione di testo direttamente chiamando setText(java.lang.CharSequence). In alcuni casi, tuttavia, puoi creare una risorsa di testo con stili che venga utilizzata anche come stringa di formato. Solitamente, non funziona perché format(String, Object...) e getString(int, Object...) metodi rimuove tutto lo stile le informazioni dalla stringa. Per risolvere il problema, devi scrivere i tag HTML con i caratteri di escape che vengono poi recuperate con fromHtml(String), dopo la formattazione. Ad esempio:

  1. Archivia la risorsa di testo con stili come stringa con escape HTML:
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>
    

    In questa stringa formattata, viene aggiunto un elemento <b>. Nota che la parentesi di apertura Con caratteri di escape HTML, utilizzando la notazione &lt;.

  2. Quindi formatta la stringa come al solito, ma richiama anche fromHtml(String) in converti il testo HTML in testo con stili applicati:

    Kotlin

    val text: String = getString(R.string.welcome_messages, username, mailCount)
    val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
    

    Java

    String text = getString(R.string.welcome_messages, username, mailCount);
    Spanned styledText = Html.fromHtml(text, FROM_HTML_MODE_LEGACY);
    

Poiché il metodo fromHtml(String) formatta tutte le entità HTML, assicurati di Esegui l'interpretazione letterale di ogni possibile carattere HTML nelle stringhe che utilizzi con il testo formattato, utilizzando htmlEncode(String). Ad esempio, se stai formattando una stringa che contiene caratteri come "<" o "&", devono essere preceduti dal carattere di escape prima della formattazione, in modo che, quando la stringa formattata viene trasmesso tramite fromHtml(String), i caratteri vengono visualizzati così come erano scritto originariamente. Ad esempio:

Kotlin

val escapedUsername: String = TextUtils.htmlEncode(username)

val text: String = getString(R.string.welcome_messages, escapedUsername, mailCount)
val styledText: Spanned = Html.fromHtml(text, FROM_HTML_MODE_LEGACY)

Java

String escapedUsername = TextUtils.htmlEncode(username);

String text = getString(R.string.welcome_messages, escapedUsername, mailCount);
Spanned styledText = Html.fromHtml(text);

Stili con gli spannable

Un Spannable è un oggetto di testo con cui puoi applicare uno stile le proprietà dei caratteri tipografici, come colore e spessore del carattere. Utilizzi SpannableStringBuilder per la creazione il testo e quindi applicare gli stili definiti in android.text.style pacchetto al testo.

Puoi utilizzare i seguenti metodi di supporto per configurare gran parte del lavoro di creazione di testo espandibile:

Kotlin

/**
 * Returns a CharSequence that concatenates the specified array of CharSequence
 * objects and then applies a list of zero or more tags to the entire range.
 *
 * @param content an array of character sequences to apply a style to
 * @param tags the styled span objects to apply to the content
 *        such as android.text.style.StyleSpan
 */
private fun apply(content: Array<out CharSequence>, vararg tags: Any): CharSequence {
    return SpannableStringBuilder().apply {
        openTags(tags)
        content.forEach { charSequence ->
            append(charSequence)
        }
        closeTags(tags)
    }
}

/**
 * Iterates over an array of tags and applies them to the beginning of the specified
 * Spannable object so that future text appended to the text will have the styling
 * applied to it. Do not call this method directly.
 */
private fun Spannable.openTags(tags: Array<out Any>) {
    tags.forEach { tag ->
        setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK)
    }
}

/**
 * "Closes" the specified tags on a Spannable by updating the spans to be
 * endpoint-exclusive so that future text appended to the end will not take
 * on the same styling. Do not call this method directly.
 */
private fun Spannable.closeTags(tags: Array<out Any>) {
    tags.forEach { tag ->
    if (length > 0) {
            setSpan(tag, 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        } else {
            removeSpan(tag)
        }
    }
}

Java

/**
 * Returns a CharSequence that concatenates the specified array of CharSequence
 * objects and then applies a list of zero or more tags to the entire range.
 *
 * @param content an array of character sequences to apply a style to
 * @param tags the styled span objects to apply to the content
 *        such as android.text.style.StyleSpan
 *
 */
private static CharSequence applyStyles(CharSequence[] content, Object[] tags) {
    SpannableStringBuilder text = new SpannableStringBuilder();
    openTags(text, tags);
    for (CharSequence item : content) {
        text.append(item);
    }
    closeTags(text, tags);
    return text;
}

/**
 * Iterates over an array of tags and applies them to the beginning of the specified
 * Spannable object so that future text appended to the text will have the styling
 * applied to it. Do not call this method directly.
 */
private static void openTags(Spannable text, Object[] tags) {
    for (Object tag : tags) {
        text.setSpan(tag, 0, 0, Spannable.SPAN_MARK_MARK);
    }
}

/**
 * "Closes" the specified tags on a Spannable by updating the spans to be
 * endpoint-exclusive so that future text appended to the end will not take
 * on the same styling. Do not call this method directly.
 */
private static void closeTags(Spannable text, Object[] tags) {
    int len = text.length();
    for (Object tag : tags) {
        if (len > 0) {
            text.setSpan(tag, 0, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            text.removeSpan(tag);
        }
    }
}

I seguenti bold, italic e color aggregano i metodi helper precedenti e mostrano esempi specifici di applicazione stili definiti nel pacchetto android.text.style. Tu puoi creare metodi simili per altri tipi di stili di testo.

Kotlin

/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
fun bold(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.BOLD))

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
fun italic(vararg content: CharSequence): CharSequence = apply(content, StyleSpan(Typeface.ITALIC))

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
fun color(color: Int, vararg content: CharSequence): CharSequence =
        apply(content, ForegroundColorSpan(color))

Java

/**
 * Returns a CharSequence that applies boldface to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence bold(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.BOLD));
}

/**
 * Returns a CharSequence that applies italics to the concatenation
 * of the specified CharSequence objects.
 */
public static CharSequence italic(CharSequence... content) {
    return apply(content, new StyleSpan(Typeface.ITALIC));
}

/**
 * Returns a CharSequence that applies a foreground color to the
 * concatenation of the specified CharSequence objects.
 */
public static CharSequence color(int color, CharSequence... content) {
    return apply(content, new ForegroundColorSpan(color));
}

Di seguito è riportato un esempio di come concatenare questi metodi per applicare vari stili a singoli parole all'interno di una frase:

Kotlin

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
val text: CharSequence = bold(italic(getString(R.string.hello)),
        color(Color.RED, getString(R.string.world)))

Java

// Create an italic "hello, " a red "world",
// and bold the entire sequence.
CharSequence text = bold(italic(getString(R.string.hello)),
    color(Color.RED, getString(R.string.world)));

Il modulo core-ktx Kotlin contiene anche funzioni di estensione che consentono di lavorare con gli intervalli è più facile. Puoi consultare le documentazione del pacchetto android.text su GitHub per saperne di più.

Per ulteriori informazioni sull'utilizzo degli intervalli, consulta i seguenti link:

Stili con annotazioni

Puoi applicare stili complessi o personalizzati utilizzando la classe Annotation insieme alla Tag <annotation> nei file di risorse settings.xml. Il tag di annotazione consente di contrassegnare parti della stringa per uno stile personalizzato definendo coppie chiave-valore personalizzate nel file XML in modo che il framework venga quindi convertito in intervalli Annotation. Puoi quindi recuperarli annotazioni e usa chiave e valore per applicare lo stile.

Quando crei annotazioni, assicurati di aggiungere <annotation> a tutte le traduzioni della stringa in ogni file hosts.xml.


Applicazione di un carattere tipografico personalizzato alla parola "testo" in tutte le lingue

Esempio: aggiunta di un carattere tipografico personalizzato

  1. Aggiungi il tag <annotation> e definisci la coppia chiave-valore. In questo caso, La chiave è font, mentre il valore è il tipo di carattere che vogliamo utilizzare: title_emphasis

    // values/strings.xml
    <string name="title">Best practices for <annotation font="title_emphasis">text</annotation> on Android</string>
    
    // values-es/strings.xml
    <string name="title"><annotation font="title_emphasis">Texto</annotation> en Android: mejores prácticas</string>
    
  2. Carica la risorsa stringa e trova le annotazioni con la chiave font. Quindi crea un intervallo personalizzato e sostituisci quello esistente.

    Kotlin

    // get the text as SpannedString so we can get the spans attached to the text
    val titleText = getText(R.string.title) as SpannedString
    
    // get all the annotation spans from the text
    val annotations = titleText.getSpans(0, titleText.length, Annotation::class.java)
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    val spannableString = SpannableString(titleText)
    
    // iterate through all the annotation spans
    for (annotation in annotations) {
       // look for the span with the key font
       if (annotation.key == "font") {
          val fontName = annotation.value
          // check the value associated to the annotation key
          if (fontName == "title_emphasis") {
             // create the typeface
             val typeface = getFontCompat(R.font.permanent_marker)
             // set the span at the same indices as the annotation
             spannableString.setSpan(CustomTypefaceSpan(typeface),
                titleText.getSpanStart(annotation),
                titleText.getSpanEnd(annotation),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
          }
       }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString
    

    Java

    // get the text as SpannedString so we can get the spans attached to the text
    SpannedString titleText = (SpannedString) getText(R.string.title);
    
    // get all the annotation spans from the text
    Annotation[] annotations = titleText.getSpans(0, titleText.length(), Annotation.class);
    
    // create a copy of the title text as a SpannableString.
    // the constructor copies both the text and the spans. so we can add and remove spans
    SpannableString spannableString = new SpannableString(titleText);
    
    // iterate through all the annotation spans
    for (Annotation annotation: annotations) {
      // look for the span with the key font
      if (annotation.getKey().equals("font")) {
        String fontName = annotation.getValue();
        // check the value associated to the annotation key
        if (fontName.equals("title_emphasis")) {
        // create the typeface
        Typeface typeface = ResourcesCompat.getFont(this, R.font.roboto_mono);
        // set the span at the same indices as the annotation
        spannableString.setSpan(new CustomTypefaceSpan(typeface),
          titleText.getSpanStart(annotation),
          titleText.getSpanEnd(annotation),
          Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
    
    // now, the spannableString contains both the annotation spans and the CustomTypefaceSpan
    styledText.text = spannableString;
    

Se utilizzi lo stesso testo più volte, devi creare la SpannableString una sola volta e riutilizzarlo secondo necessità per evitare potenziali prestazioni e memoria che le applicazioni presentino problemi di prestazioni.

Per altri esempi di utilizzo delle annotazioni, consulta Stile del testo internazionalizzato in Android

Intervalli di annotazioni e suddivisione in partizioni di testo

Poiché anche gli intervalli Annotation sono ParcelableSpans, la coppia chiave-valore le coppie sono divise e non pacchettizzate. Finché il destinatario del pacco sa come interpretare le annotazioni, puoi utilizzare Annotation sezioni per applicare stili personalizzati il testo particellare.

Per mantenere lo stile personalizzato quando passi il testo a un bundle di intent, devi prima aggiungere Annotation si estende al testo. Puoi farlo nelle risorse XML tramite il <annotazione> come mostrato nell'esempio precedente, o nel codice creando un nuovo Annotation e impostandolo come intervallo, come mostrato di seguito:

Kotlin

val spannableString = SpannableString("My spantastic text")
val annotation = Annotation("font", "title_emphasis")
spannableString.setSpan(annotation, 3, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

// start Activity with text with spans
val intent = Intent(this, MainActivity::class.java)
intent.putExtra(TEXT_EXTRA, spannableString)
startActivity(intent)

Java

SpannableString spannableString = new SpannableString("My spantastic text");
Annotation annotation = new Annotation("font", "title_emphasis");
spannableString.setSpan(annotation, 3, 7, 33);

// start Activity with text with spans
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(TEXT_EXTRA, spannableString);
this.startActivity(intent);

Recupera il testo da Bundle come SpannableString e poi analizza alle annotazioni, come mostrato nell'esempio precedente.

Kotlin

// read text with Spans
val intentCharSequence = intent.getCharSequenceExtra(TEXT_EXTRA) as SpannableString

Java

// read text with Spans
SpannableString intentCharSequence = (SpannableString)intent.getCharSequenceExtra(TEXT_EXTRA);

Per ulteriori informazioni sullo stile del testo, consulta i seguenti link: