مصادر السلاسل النصية (طرق العرض)

المفاهيم والتنفيذ في Jetpack Compose

يوفر مصدر السلاسل النصية سلاسل نصية لتطبيقك مع خيارات لتنسيق النص وتصميمه. هناك ثلاثة أنواع من الموارد التي يمكن أن توفّر لتطبيقك السلاسل:

String
ملف XML للموارد يوفّر سلسلة واحدة.
مصفوفة السلسلة
ملف XML للموارد يوفّر مصفوفة من السلاسل.
سلاسل الكمية (صيغ الجمع)
ملف XML للموارد يحتوي على سلاسل مختلفة للجمع.

يمكن تطبيق بعض ترميز التنسيق ومعلَمات التنسيق على جميع السلاسل. للحصول على معلومات حول تنسيق السلاسل وتصميمها، راجِع القسم حول التنسيق والتصميم.

سلسلة

سلسلة واحدة يمكن الرجوع إليها من التطبيق أو من ملفات موارد أخرى (مثل تنسيق XML).

موقع الملف:
res/values/filename.xml
اسم الملف اختياري. يتم استخدام name الخاص بالعنصر <string> كمعرّف للمورد.
نوع بيانات المورد المجمَّع:
مؤشر المورد إلى String
مرجع المورد:
في Java: R.string.string_name
في XML: @string/string_name
بنية الجملة:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string
        name="string_name"
        >text_string</string>
</resources>
العناصر:
<resources>
مطلوبة. يجب أن تكون هذه هي العقدة الجذرية.

ما مِن سمات.

<string>
سلسلة يمكن أن تتضمّن علامات تنسيق يُرجى العلم أنّه يجب إلغاء علامات الاقتباس المفردة والمزدوجة. لمزيد من المعلومات حول كيفية تحديد نمط السلاسل وتنسيقها بشكل صحيح، يُرجى الاطّلاع على التنسيق وتحديد النمط أدناه.

السمات:

name
String. اسم السلسلة. يُستخدَم هذا الاسم كمعرّف المورد.
مثلا:
تم حفظ ملف XML في res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources>

تطبِّق لغة XML الخاصة بالتصميم سلسلة على طريقة العرض:

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

يستردّ الرمز البرمجي للتطبيق التالي سلسلة:

Kotlin

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

Java

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

يمكنك استخدام getString(int) أو getText(int) لاسترداد سلسلة. تحتفظ getText(int) بأي نمط نص منسّق تم تطبيقه على السلسلة.

مصفوفة السلاسل النصية

مجموعة من السلاسل التي يمكن الرجوع إليها من التطبيق

موقع الملف:
res/values/filename.xml
اسم الملف اختياري. يتم استخدام name الخاص بالعنصر <string-array> كمعرّف للمورد.
نوع بيانات المورد المجمَّع:
مؤشر الموارد إلى مصفوفة من String.
مرجع المورد:
في Java: R.array.string_array_name
في XML: @[package:]array/string_array_name
بنية الجملة:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
        name="string_array_name">
        <item
            >text_string</item>
    </string-array>
</resources>
العناصر:
<resources>
مطلوبة. يجب أن تكون هذه هي العقدة الجذرية.

ما مِن سمات.

<string-array>
تحدّد هذه السمة مصفوفة من السلاسل. يحتوي على عنصر واحد أو أكثر من عناصر <item>.

السمات:

name
String. اسم المصفوفة. يُستخدَم هذا الاسم كمعرّف المورد للإشارة إلى الصفيف.
<item>
سلسلة يمكن أن تتضمّن علامات تنسيق يمكن أن تكون القيمة مرجعًا إلى مورد سلسلة آخر. يجب أن يكون عنصرًا فرعيًا من عنصر <string-array>. يُرجى العِلم أنّه يجب إلغاء علامات الاقتباس المفردة والمزدوجة. راجِع القسم التنسيق والأسلوب أدناه للحصول على معلومات حول كيفية تنسيق السلاسل وتحديد أسلوبها بشكلٍ سليم.

ما مِن سمات.

مثلا:
تم حفظ ملف XML في 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>
يستردّ الرمز البرمجي للتطبيق هذا مصفوفة السلاسل النصية:

Kotlin

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

Java

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

سلاسل الكمية (صيغ الجمع)

تختلف اللغات في قواعد المطابقة النحوية مع الكمية. في اللغة الإنجليزية، على سبيل المثال، الكمية 1 هي حالة خاصة. نكتب "كتاب واحد"، ولكن بالنسبة إلى أي كمية أخرى، نكتب "n كتاب". هذا التمييز بين المفرد والجمع شائع جدًا، ولكن بعض اللغات الأخرى تميّز بينهما بشكل أدق. المجموعة الكاملة المتوافقة مع Android هي zero وone وtwo وfew وmany وother.

يمكن أن تكون قواعد تحديد حالة الاستخدام للغة وكمية معيّنتَين معقّدة للغاية، لذا يوفّر لك نظام التشغيل Android طرقًا، مثل getQuantityString()، لاختيار المورد المناسب لك.

في الإصدار 24 من واجهة برمجة التطبيقات أو الإصدارات الأحدث، يمكنك استخدام فئة ICU MessageFormat الأكثر فعالية.

موقع الملف:
res/values/filename.xml
اسم الملف اختياري. يتم استخدام name الخاص بالعنصر <plurals> كمعرّف للمورد.
مرجع المورد:
في Java: R.plurals.plural_name
بنية الجملة:
<?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>
العناصر:
<resources>
مطلوبة. يجب أن تكون هذه هي العقدة الجذرية.

ما مِن سمات.

<plurals>
مجموعة من السلاسل، يتم توفير إحدى السلاسل منها استنادًا إلى مقدار شيء ما. يحتوي على عنصر واحد أو أكثر من عناصر <item>.

السمات:

name
String. اسم لزوج السلاسل. يُستخدَم هذا الاسم كمعرّف للمورد.
</dd>

<item>
سلسلة مفرد أو جمع يمكن أن تكون القيمة مرجعًا إلى مورد سلسلة آخر. يجب أن يكون عنصرًا فرعيًا من عنصر <plurals>. يُرجى العلم أنّه يجب تخطّي علامات الاقتباس المفردة والمزدوجة. راجِع القسم التنسيق والتصميم أدناه للحصول على معلومات حول كيفية تصميم السلاسل وتنسيقها بشكل صحيح.

السمات:

quantity
الكلمة الرئيسية: قيمة تشير إلى وقت استخدام هذه السلسلة. القيم الصالحة، مع أمثلة غير شاملة بين قوسين:
القيمةالوصف
zeroعندما تتطلّب اللغة معاملة خاصة للرقم 0 (كما هو الحال في اللغة العربية)
oneعندما تتطلّب اللغة معاملة خاصة للأرقام مثل الرقم واحد (كما هو الحال مع الرقم 1 في اللغة الإنجليزية ومعظم اللغات الأخرى؛ في اللغة الروسية، أي رقم ينتهي بالرقم 1 ولكن لا ينتهي بالرقم 11 يندرج في هذه الفئة).
twoعندما تتطلّب اللغة معاملة خاصة للأرقام، مثل الرقم 2 (كما هو الحال في اللغة الويلزية، أو 102 في اللغة السلوفينية).
fewعندما تتطلّب اللغة معاملة خاصة للأرقام "الصغيرة" (كما هو الحال مع الأرقام 2 و3 و4 في التشيكية، أو الأرقام التي تنتهي بـ 2 أو 3 أو 4 ولكن ليس 12 أو 13 أو 14 في البولندية)
manyعندما تتطلّب اللغة معاملة خاصة للأعداد "الكبيرة" (كما هو الحال مع الأعداد التي تنتهي من 11 إلى 99 في اللغة المالطية)
otherعندما لا تتطلّب اللغة معاملة خاصة للكمية المحدّدة (كما هو الحال مع جميع الأرقام باللغة الصينية، أو الرقم 42 باللغة الإنجليزية)

مثلا:
تم حفظ ملف XML في 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>

تم حفظ ملف XML في 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>

الاستخدام:

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

عند استخدام طريقة getQuantityString()، عليك تمرير count مرتين إذا كانت السلسلة تتضمّن تنسيق السلسلة. على سبيل المثال، بالنسبة إلى السلسلة %d songs found، تحدّد المَعلمة الأولى count سلسلة الجمع المناسبة، ويتم إدراج المَعلمة الثانية count في العنصر النائب %d. إذا كانت سلاسل الأعداد الجمع لا تتضمّن تنسيق السلسلة، لن تحتاج إلى تمرير المَعلمة الثالثة إلى getQuantityString.

التنسيق والنمط

في ما يلي بعض النقاط المهمة التي يجب معرفتها حول كيفية تنسيق موارد السلاسل وتصميمها بشكل صحيح.

سلاسل التنسيق

إذا كنت بحاجة إلى تنسيق السلاسل، يمكنك إجراء ذلك عن طريق وضع وسيطات التنسيق في مورد السلسلة، كما هو موضّح في مثال المورد التالي.

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

في هذا المثال، تحتوي سلسلة التنسيق على وسيطتَين: %1$s هي سلسلة و%2$d هو عدد عشري. بعد ذلك، يمكنك تنسيق السلسلة من خلال استدعاء getString(int, Object...). على سبيل المثال:

Kotlin

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

Java

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

تحديد الأنماط باستخدام ترميز HTML

يمكنك إضافة أنماط إلى السلاسل باستخدام ترميز HTML. على سبيل المثال:

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

إذا لم تكن تريد تطبيق تنسيق، يمكنك ضبط نص TextView مباشرةً من خلال استدعاء setText(java.lang.CharSequence). في بعض الحالات، قد تحتاج إلى إنشاء مصدر نص منمّق يُستخدَم أيضًا كسلسلة تنسيق. لا يمكن عادةً إجراء ذلك لأنّ الطريقتَين format(String, Object...) وgetString(int, Object...) تزيلان كل معلومات التنسيق من السلسلة. الحلّ البديل لذلك هو كتابة علامات HTML باستخدام كيانات تم تجاهلها، ثم استردادها باستخدام fromHtml(String) بعد اكتمال عملية التنسيق. على سبيل المثال:

  1. خزِّن مورد النص المنسّق كسلسلة تم تجاهل أحرف HTML الخاصة فيها:
    <resources>
      <string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>
    </resources>

    في هذه السلسلة المنسَّقة، تتم إضافة عنصر <b>. لاحظ أنّ قوس الفتح تم تحويله إلى تنسيق HTML باستخدام الترميز &lt;.

  2. بعد ذلك، يمكنك تنسيق السلسلة كالمعتاد، ولكن عليك أيضًا استدعاء fromHtml(String) لتحويل نص HTML إلى نص منسّق:

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

بما أنّ طريقة fromHtml(String) تنسّق جميع عناصر HTML، احرص على إلغاء أي أحرف HTML محتملة في السلاسل التي تستخدمها مع النص المنسّق، وذلك باستخدام htmlEncode(String). على سبيل المثال، إذا كنت بصدد تنسيق سلسلة تتضمّن أحرفًا مثل "<" أو "&"، يجب إلغاء هذه الأحرف قبل التنسيق، وذلك لكي تظهر الأحرف بالطريقة التي كُتبت بها في الأصل عند تمرير السلسلة المنسَّقة من خلال fromHtml(String). على سبيل المثال:

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

تطبيق الأنماط باستخدام عناصر قابلة للضبط

Spannable هو عنصر نصي يمكنك تنسيقه باستخدام خصائص خط الطباعة، مثل اللون ووزن الخط. يمكنك استخدام SpannableStringBuilder لإنشاء النص ثم تطبيق الأنماط المحددة في حزمة android.text.style على النص.

يمكنك استخدام طرق المساعدة التالية لإعداد معظم العمليات اللازمة لإنشاء نص قابل للتوسيع:

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 وcolor الطرق المساعدة المذكورة أعلاه، وتوضّح أمثلة محدّدة على تطبيق الأنماط المحدّدة في حزمة android.text.style. يمكنك إنشاء طرق مشابهة لتطبيق أنماط أخرى على النصوص.

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

في ما يلي مثال على كيفية ربط هذه الطرق معًا لتطبيق أنماط مختلفة على كلمات فردية ضمن عبارة:

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

تحتوي وحدة core-ktx Kotlin أيضًا على دوال إضافية تسهّل العمل مع النطاقات. يمكنك الاطّلاع على android.text في مستندات الحزمة على GitHub لمعرفة المزيد.

لمزيد من المعلومات حول استخدام النطاقات، يُرجى الاطّلاع على الروابط التالية:

تنسيق باستخدام التعليقات التوضيحية

يمكنك تطبيق أنماط معقّدة أو مخصّصة باستخدام الفئة Annotation مع العلامة <annotation> في ملفات موارد strings.xml. تتيح لك علامة التعليق التوضيحي تحديد أجزاء من السلسلة لتطبيق أنماط مخصّصة عليها من خلال تحديد أزواج المفتاح/القيمة المخصّصة في ملف XML الذي يحوّله إطار العمل بعد ذلك إلى نطاقات Annotation. يمكنك بعد ذلك استرداد هذه التعليقات التوضيحية واستخدام المفتاح والقيمة لتطبيق التنسيق.

عند إنشاء التعليقات التوضيحية، احرص على إضافة العلامة <annotation> إلى جميع ترجمات السلسلة في كل ملف strings.xml.


تطبيق خط مخصّص على كلمة "نص" بجميع اللغات

مثال: إضافة خط مخصّص

  1. أضِف العلامة <annotation>، وحدِّد زوج المفتاح/القيمة. في هذه الحالة، يكون المفتاح هو font، والقيمة هي نوع الخط الذي نريد استخدامه: 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. حمِّل مصدر السلاسل النصية وابحث عن علامات التوضيح باستخدام المفتاح font. بعد ذلك، أنشئ نطاقًا مخصّصًا واستبدِل النطاق الحالي به.

    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;

إذا كنت تستخدم النص نفسه عدة مرات، عليك إنشاء عنصر SpannableString مرة واحدة وإعادة استخدامه حسب الحاجة لتجنُّب المشاكل المحتملة في الأداء والذاكرة.

لمزيد من الأمثلة حول استخدام التعليقات التوضيحية، راجِع تنسيق النصوص المترجمة في Android.

نطاقات التعليقات التوضيحية وتقسيم النص

بما أنّ نطاقات Annotation هي أيضًا ParcelableSpans، يتم تجميع أزواج المفاتيح والقيم وتفكيكها. طالما أنّ مستلِم الحزمة يعرف كيفية تفسير التعليقات التوضيحية، يمكنك استخدام نطاقات Annotation لتطبيق أنماط مخصّصة على النص الذي تمّت حزمته.

للحفاظ على النمط المخصّص عند تمرير النص إلى حزمة Intent، عليك أولاً إضافة نطاقات Annotation إلى النص. يمكنك إجراء ذلك في موارد XML باستخدام العلامة <annotation>، كما هو موضّح في المثال أعلاه، أو في الرمز البرمجي من خلال إنشاء Annotation جديد وضبطه كمدى، كما هو موضّح أدناه:

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

استرجِع النص من Bundle كـ SpannableString، ثم حلِّل التعليقات التوضيحية المرفقة، كما هو موضّح في المثال أعلاه.

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

لمزيد من المعلومات حول تنسيق النص، يُرجى الاطّلاع على الروابط التالية: