Ciągi tekstowe

Zasób ciągu tekstowego dostarcza ciągi tekstowe dotyczące aplikacji z opcjonalnymi ustawieniami stylu i formatowania tekstu. Istnieją 3 typy zasobów, które mogą zapewnić do aplikacji z ciągami znaków:

String
Zasób XML, który zawiera jeden ciąg znaków.
Tablica ciągów
Zasób XML zawierający tablicę ciągów znaków.
Ciągi tekstowe z liczbą (liczba mnoga)
Zasób XML, który zawiera różne ciągi znaków na potrzeby liczby mnogiej.

We wszystkich ciągach można stosować pewne znaczniki stylu i argumenty formatowania. Dla: informacje o stylach i formatowaniu ciągów tekstowych znajdziesz w sekcji Formatowanie i styl.

Ciąg znaków

Pojedynczy ciąg, do którego można się odwołać z aplikacji lub innych plików zasobów (np. jako układ XML).

Uwaga: ciąg to prosty zasób, do którego się odwołuje się za pomocą wartości podanej w atrybucie name (nie nazwy pliku XML). Możesz więc połączyć zasoby łańcuchowe z innymi prostymi zasobami w jednym pliku XML, w ramach jednego elementu <resources>.

lokalizacja pliku:

res/values/filename.xml(
) Nazwa pliku jest dowolna. Atrybut name elementu <string> jest używany jako identyfikatora zasobu.
skompilowany typ danych zasobu:
Wskaźnik zasobu do elementu String.
odniesienie do zasobu:
W języku Java: R.string.string_name
W pliku XML:@string/string_name
składnia:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string
        name="string_name"
        >text_string</string>
</resources>
elementy:
<resources>
Wymagane. Musi to być węzeł główny.

Brak atrybutów.

<string>
Ciąg znaków, który może zawierać tagi stylu. Uważaj, aby nie pominąć apostrofów, cudzysłowów. Więcej informacji o prawidłowym stylu i formatowaniu ciągów tekstowych znajdziesz w sekcji Formatowanie i styl poniżej.

atrybuty:

name
Ciąg znaków. Nazwa ciągu znaków. Ta nazwa jest używana jako zasób ID.
przykład:
Plik XML zapisany o res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>

Ten układ XML stosuje ciąg znaków do widoku:

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

Ten kod aplikacji pobiera ciąg znaków:

Kotlin

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

Java

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

Możesz użyć: getString(int) lub getText(int), aby pobrać ciąg znaków. getText(int) zachowuje wszystkie style tekstu sformatowanego zastosowane do ciągu znaków.

Tablica z ciągiem znaków

Tablica ciągów tekstowych, do których aplikacja może się odwołać.

Uwaga: tablica ciągu znaków jest prostym zasobem, do którego się odwołuje za pomocą wartości podanej w atrybucie name (nie nazwy pliku XML). Jako więc możesz połączyć zasoby tablicy ciągu z innymi prostymi zasobami w jednym pliku XML, w ramach jednego elementu <resources>.

lokalizacja pliku:

res/values/filename.xml(
) Nazwa pliku jest dowolna. Atrybut name elementu <string-array> jest używany jako identyfikatora zasobu.
skompilowany typ danych zasobu:
Wskaźnik zasobu do tablicy String.
odniesienie do zasobu:
W języku Java: R.array.string_array_name
W pliku XML: @[package:]array/string_array_name
składnia:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
        name="string_array_name">
        <item
            >text_string</item>
    </string-array>
</resources>
elementy:
<resources>
Wymagane. Musi to być węzeł główny.

Brak atrybutów.

<string-array>
Definiuje tablicę ciągów znaków. Zawiera co najmniej 1 element <item>.

atrybuty:

name
Ciąg znaków. Nazwa tablicy. Ta nazwa jest używana jako zasób Identyfikator odwołania do tablicy.
<item>
Ciąg znaków, który może zawierać tagi stylu. Wartość może być odwołaniem do innego zasób tekstowy. Musi być elementem podrzędnym elementu <string-array>. Strzeżcie się, muszą uniknąć apostrofów cudzysłowów. Zobacz poniżej Formatowanie i style. aby odpowiednio stylizować i formatować ciągi.

Brak atrybutów.

przykład:
Plik XML zapisany o 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>

Ten kod aplikacji pobiera tablicę ciągu znaków:

Kotlin

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

Java

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

Ciągi znaków dotyczące ilości (liczba mnoga)

W przypadku różnych języków obowiązują różne reguły gramatyczne zgodności z ilością. W języku angielskim, Na przykład szczególnym przypadkiem jest liczba 1. Wpisujemy „1 książkę”, ale w przypadku każdej innej liczby wpisz „n książek”. Takie rozróżnienie między liczbą pojedynczą i mnogą jest bardzo powszechne, ale występuje też w różnych językach. Pełny zestaw obsługiwany przez Androida to zero, one, two, few, many i other.

Reguły decydujące o tym, który przypadek zastosować w przypadku danego języka i ilości, mogą być bardzo złożone, Android oferuje metody, takie jak getQuantityString(), aby wybrać odpowiednie źródło informacji.

Chociaż wcześniej był nazywany „ciągiem ilościowym” (i nadal nazywany w interfejsie API) W przypadku liczby mnogiej ciągi tekstowe powinny być używane tylko. Błędem byłoby użycie ciągów znaków typu quantity w celu zaimplementować coś takiego jak „Odebrane” w Gmailu a „Odebrane (12)” gdy pojawią się nieprzeczytane wiadomości, na przykład. Warto użyć ciągów tekstowych typu quantity zamiast instrukcji if, ale trzeba pamiętać, że w niektórych językach (np. chińskim) w ogóle nie występują różnice, więc zawsze otrzymasz ciąg other.

Ich wybór zależy wyłącznie od konieczności gramatycznej. W języku angielskim ciąg znaków funkcji zero jest ignorowany, nawet jeśli liczba wynosi 0, ponieważ 0 nie różni się gramatycznie od 2 ani żadnymi innymi liczbami oprócz 1 („zero książek”, „jedna książka”); „dwie książki” itd.). W języku koreańskim tylko ciąg other to jaka kiedykolwiek była używana.

Nie daj się też wprowadzić w błąd, jeśli na przykład two może mieć zastosowanie tylko do: liczba 2: język może wymagać, aby znaki 2, 12, 102 (itd.) były traktowane jak jeden ale w inny sposób niż w przypadku innych. Zdaj się na tłumacza, który pomoże Ci zrozumieć różnice ich język się nakłada.

Jeśli Twoja wiadomość nie zawiera liczby produktów, prawdopodobnie nie jest odpowiednim kandydatem do liczba mnoga. Na przykład w języku litewskim do cyfr 1 i 101 używane są formy liczby pojedynczej, więc „1 książka” to przetłumaczone jako „1 knyga” i „101 książek” jest tłumaczone jako „101 knyga”. Tymczasem „książka” to „knyga” i „wiele książek” to „daug knygų”. Jeśli wiadomość w liczbie mnogiej w języku angielskim zawiera słowo „książka” (pojedyncza) i „wiele książek” (liczba mnoga) bez rzeczywista liczba może zostać przetłumaczona jako „knyga”, (książka)/„daug knygų” (wiele książek), ale Litewskie reguły, wyświetla się „knyga” (pojedyncza książka), gdy na przykład liczba to 101.

Często można uniknąć ciągów znaków ilości, stosując formuły neutralne pod względem ilości, takie jak „Książki: 1”. Utrudnia to życie Tobie i tłumaczom znacznie ułatwia funkcjonowanie, o ile są one akceptowalne w danej aplikacji.

W interfejsie API w wersji 24 i nowszych możesz używać znacznie wydajniejszej ICU MessageFormat lekcję.

Uwaga: kolekcja w liczbie mnogiej to prosty zasób, który jest można się odwoływać za pomocą wartości podanej w atrybucie name (a nie nazwy pliku XML) ). Dzięki temu można połączyć zasoby w liczbie mnogiej z innymi prostymi zasobami w jednym XML w ramach 1 elementu <resources>.

lokalizacja pliku:

res/values/filename.xml(
) Nazwa pliku jest dowolna. Atrybut name elementu <plurals> jest używany jako identyfikatora zasobu.
odniesienie do zasobu:
W języku Java: R.plurals.plural_name
składnia:
<?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>
elementy:
<resources>
Wymagane. Musi to być węzeł główny.

Brak atrybutów.

<plurals>
Zbiór ciągów tekstowych, z których jeden jest podawany w zależności od ilości coś. Zawiera co najmniej 1 element <item>.

atrybuty:

name
Ciąg znaków. Nazwa pary ciągów. Ta nazwa jest używana jako identyfikatora zasobu.
<item>
Ciąg w liczbie mnogiej lub pojedynczej. Wartość może być odwołaniem do innego zasób tekstowy. Musi być elementem podrzędnym elementu <plurals>. Należy pamiętać, apostrofów i cudzysłowów. Patrz sekcja Formatowanie i Styl (poniżej), aby uzyskać informacje na temat prawidłowego stylu i formatowania ciągów tekstowych.

atrybuty:

quantity
Słowo kluczowe. Wartość wskazująca, kiedy należy używać tego ciągu znaków. Prawidłowa wartości z niewyczerpującymi przykładami w nawiasach:
WartośćOpis
zeroKiedy język wymaga specjalnego traktowania liczby 0 (jak w języku arabskim).
oneLiczby w języku angielskim należy traktować w szczególny sposób, tak jak w przypadku liczby 1 w języku angielskim i większości innych języków. W języku rosyjskim klasa obejmuje wszystkie numery kończące się na 1, ale nie takie jak 11.
twoKiedy język wymaga specjalnego traktowania liczby w rodzaju 2 (np. „2” w walijskim lub „102” w słoweńskim).
fewgdy język wymaga szczególnego traktowania słów „małych”; (np. 2, 3 i 4 w języku czeskim lub cyfry kończące się cyframi 2, 3 i 4, ale nie 12, 13 ani 14 w języku polskim).
manygdy język wymaga szczególnego traktowania słowa „duży”; numerów (jak w przypadku numerów kończących się na 11–99 w języku maltańskim).
otherGdy język nie wymaga szczególnego traktowania danej ilości (jak w przypadku wszystkich liczb w języku chińskim lub 42 w języku angielskim).
przykład:
Plik XML zapisany o 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>

Plik XML zapisany w lokalizacji 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>

Wykorzystanie:

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

Jeśli używasz metody getQuantityString(), musisz przekazać count dwukrotnie, jeśli ciąg zawiera formatowanie ciągu znaków za pomocą liczby. Na przykład w przypadku ciągu %d songs found, pierwszy parametr count wybiera odpowiedni ciąg w liczbie mnogiej i drugi parametr count jest wstawiony do zmiennej %d. Jeśli liczba mnoga ciągi znaków nie zawierają formatowania ciągów znaków, nie trzeba przekazywać trzeciego parametru do funkcji getQuantityString.

Format i styl

Oto kilka ważnych informacji o tym, jak prawidłowo określać formatowanie zasobów z ciągami tekstowymi i określić ich styl.

Obsługa znaków specjalnych

Jeśli ciąg zawiera znaki o specjalnym wykorzystaniu w kodzie XML, musisz użyć znaku zmiany znaczenia zgodnie ze standardowymi regułami zmiany znaczenia znaków XML/HTML. Jeśli chcesz zmienić znaczenie znaku ma specjalne znaczenie w Androidzie, dlatego należy użyć poprzedzającego ukośnika lewego.

Domyślnie Android zwija sekwencje znaków odstępów w jedną spację. Aby tego uniknąć, umieść odpowiednią część ciągu znaków w cudzysłowie. W tym przypadku wszystkie znaki odstępu (w tym nowe wiersze) są zachowywane w obszarze cytowanym. Podwójny cudzysłów pozwala także używać pojedynczych cudzysłowów bez zmiany znaczenia.

Znak Formularze ze zmianą znaczenia
@ \@
? \?
Nowy wiersz \n
Tab \t
Znak Unicode U+XXXX \uXXXX
Cudzysłów pojedynczy (')

Dowolny z tych:

  • \'
  • Umieść cały ciąg w cudzysłowach. (np. "This'll work")
Podwójny cudzysłów (") \"

Pamiętaj, że otoczenie ciągu znaków pojedynczymi cudzysłowami nie działa.

Zwijanie się pustej przestrzeni i ucieczka z Androida zdarzają się po jest analizowany jako XML. Oznacza to, że <string> &#32; &#8200; &#8195;</string> (spacja, spacja interpunkcyjna, spacja Unicode Em) zwijają się do jednej spacji (" "), ponieważ po analizie pliku jako XML są to wszystkie spacje Unicode. Aby zachować te pokoje w niezmienionej formie, możesz je zacytować (<string>" &#32; &#8200; &#8195;"</string>) lub kodu ucieczki Androida (<string> \u0032 \u8200 \u8195</string>).

Uwaga: z punktu widzenia parsera XML nie ma różnicy między <string>"Test this"</string> i <string>&quot;Test this&quot;</string>. Obie formy nie wyświetla żadnych cudzysłowów, tylko wyświetla cudzysłowy z zachowaniem odstępów między znakami systemu Android (który nie efekt praktyczny w tym przypadku).

Ciągi formatowania

Jeśli chcesz sformatować ciągi znaków, możesz to zrobić, umieszczając argumenty formatu w zasobie ciągu znaków, jak pokazano w przykładzie poniżej.

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

W tym przykładzie ciąg tekstowy formatu ma 2 argumenty: %1$s to ciąg znaków i %2$d jest liczbą dziesiętną. Następnie sformatuj ciąg, wywołując funkcję getString(int, Object...). Na przykład:

Kotlin

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

Java

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

Stylizowanie za pomocą znaczników HTML

Do ciągów tekstowych możesz dodać odpowiedni styl za pomocą znaczników HTML. Na przykład:

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

Obsługiwane są te elementy HTML:

  • Pogrubienie: <b>
  • Kursywa: <i>, <cite>, <dfn>, <em>
  • 25% większy tekst: <big>
  • O 20% mniejszy tekst: <small>
  • Ustawianie właściwości czcionki: <font face=”font_family“ color=”hex_color”>. Przykłady możliwe rodziny czcionek to monospace, serif oraz sans_serif
  • Ustawianie rodziny czcionek o stałej szerokości: <tt>
  • Przekreślenie: <s>, <strike>, <del>
  • Podkreślenie: <u>
  • Indeks górny: <sup>
  • Indeks dolny: <sub>
  • punktory: <ul>, <li>.
  • podziały wierszy: <br>
  • Dział: <div>
  • Styl CSS: <span style=”color|background_color|text-decoration”>
  • Akapity: <p dir=”rtl | ltr” style=”...”>

Jeśli nie stosujesz formatowania, możesz ustawić tekst TextView bezpośrednio, wywołując setText(java.lang.CharSequence) W niektórych przypadkach możesz jednak chcesz utworzyć zasób tekstowy z określonym stylem, który będzie również używany jako ciąg tekstowy formatu. Normalnie nie działa, ponieważ format(String, Object...) i getString(int, Object...) metod usuwa cały styl informacje z ciągu znaków. Aby obejść ten problem, zapisz tagi HTML ze znakami zmiany znaczenia. elementy, które są następnie przywracane za pomocą fromHtml(String), po sformatowaniu. Na przykład:

  1. Przechowuj zasób tekstowy ze stylem pod postacią ciągu znaków HTML ze zmianą znaczenia:
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>
    

    W tym sformatowanym ciągu znaków dodawany jest element <b>. Zwróć uwagę, że nawias otwierający jest Kod HTML ze zmianą znaczenia, w formacie &lt;.

  2. Następnie sformatuj ciąg w zwykły sposób, ale wywołaj funkcję fromHtml(String) w celu przekonwertować tekst HTML na tekst ze stylem:

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

Metoda fromHtml(String) formatuje wszystkie encje HTML, więc pamiętaj wszelkie możliwe znaki HTML w ciągach znaków użytych w przypadku sformatowanego tekstu, za pomocą funkcji htmlEncode(String) Na przykład podczas formatowania ciągu zawierającego znaki takie jak „<” lub „&”, należy zmienić ich znaczenie przed sformatowaniem. Dzięki temu podczas jest przechodzi przez funkcję fromHtml(String), postacie wyglądają tak, jak były jego autora. Na przykład:

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

Style z elementami rozciąganymi

Spannable to obiekt tekstowy, którego styl możesz określić właściwości kroju czcionki, takie jak kolor i grubość czcionki. Używasz SpannableStringBuilder do skompilowania w tekście, a następnie zastosuj style zdefiniowane w tagu android.text.style do tekstu.

Aby skonfigurować znaczną część pracy, możesz użyć tych metod pomocniczych tworzenia tekstu rozpinającego:

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

bold, italic i color opakować powyższe metody pomocnicze i zademonstrować konkretne przykłady ich zastosowania stylów zdefiniowanych w pakiecie android.text.style. Ty mogą tworzyć podobne metody do wprowadzania innych rodzajów stylu tekstu.

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

Oto przykład łączenia tych metod w celu zastosowania różnych stylów w poszczególnych słowa w wyrażeniu:

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

Moduł Core-ktx Kotlin zawiera też funkcje rozszerzeń, dzięki którym praca ze spanami jest równomierna. . Informacje na temat dokumentacji pakietu android.text w GitHubie.

Więcej informacji o pracy ze spanami znajdziesz w tych artykułach:

Styl z adnotacjami

Styl złożony lub niestandardowy możesz zastosować, używając klasy Annotation w połączeniu z parametrem <annotation> w plikach zasobów string.xml. Tag adnotacji umożliwia możesz oznaczyć fragmenty ciągu znaków do niestandardowego stylu przez zdefiniowanie niestandardowych par klucz-wartość w pliku XML. i przekształca je w spany Annotation. Dzięki temu można je pobrać i użyj klucza oraz wartości, aby zastosować styl.

Tworząc adnotacje, pamiętaj o dodaniu znaczników <annotation> do wszystkich tłumaczeń ciągu znaków w każdym pliku string.xml.

,
Dodanie kroju niestandardowego czcionki do słowa „tekst” we wszystkich językach

Przykład - dodawanie niestandardowego kroju czcionki

  1. Dodaj tag <annotation> i zdefiniuj parę klucz-wartość. W tym przypadku parametr klucz to font, a wartością jest rodzaj czcionki, którego mamy użyć: 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. Wczytaj zasób z ciągiem znaków i odszukaj adnotacje za pomocą klucza font. Następnie utwórz niestandardowy i zastąpić istniejący.

    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;
    

Jeśli tego samego tekstu używasz wiele razy, utwórz Obiekt SpannableString raz i używaj go w razie potrzeby, aby uniknąć potencjalnej wydajności i pamięci problemów.

Więcej przykładów użycia adnotacji znajdziesz tutaj: Styl umiędzynarodowionego tekstu na Androidzie

Rozpiętości adnotacji i pakowanie tekstu

Rozpiętości Annotation to również ParcelableSpans, więc para klucz-wartość w parach. Jeśli odbiorca wie, jak interpretować paczkę na potrzeby adnotacji, możesz użyć Annotation rozpiętości, aby zastosować własny styl części tekstu.

Aby zachować niestandardowy styl podczas przekazywania tekstu do pakietu intencji, musisz najpierw dodać Annotation rozciąga się do tekstu. Możesz to zrobić w zasobach XML za pomocą pliku <adnotacja> jak w przykładzie powyżej, lub w kodzie, tworząc nowy tag Annotation i ustawiam go jako span, jak pokazano poniżej:

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

Pobierz tekst z narzędzia Bundle jako SpannableString i przeanalizuj go z załączonych adnotacji, tak jak widać w przykładzie powyżej.

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

Więcej informacji o stylach tekstu znajdziesz na tych stronach: