يوفر مورد السلاسل سلاسل نصية لتطبيقك مع تصميم وتنسيق نصي اختياري. هناك ثلاثة أنواع من الموارد التي يمكن أن تزود تطبيقك بالسلاسل:
- String
- مورد XML يوفر سلسلة واحدة
- مصفوفة السلاسل
- مورد XML يوفّر مجموعة من السلاسل.
- سلاسل الكمية (الصيغ الزخرفية)
- مورد XML يتضمّن سلاسل مختلفة للجمع
كافة السلاسل قادرة على تطبيق بعض ترميزات النمط والتنسيقات. للحصول على معلومات حول الأنماط وتنسيق السلاسل، راجع القسم الذي يتناول التنسيق والتصميم.
سلسلة
سلسلة واحدة يمكن الإشارة إليها من التطبيق أو من ملفات موارد أخرى (مثل تنسيق XML).
ملاحظة:السلسلة هي مورد بسيط تتم الإشارة إليه
باستخدام القيمة المقدَّمة في السمة name
(وليس اسم ملف XML). بالتالي، يمكنك دمج موارد السلسلة مع موارد أخرى بسيطة في ملف XML واحد ضمن عنصر <resources>
واحد.
- موقع الملف:
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>
- العناصر:
- مثلا:
- تم حفظ ملف 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" />
يسترد رمز التطبيق هذا سلسلة:
يمكنك استخدام
getString(int)
أوgetText(int)
لاسترداد سلسلة. تحتفظgetText(int)
بأي نمط نص منسق مطبّق على السلسلة.
مصفوفة السلاسل
مصفوفة من السلاسل التي يمكن الإشارة إليها من التطبيق.
ملاحظة: مصفوفة السلاسل هي مورد بسيط تتم الإشارة إليه
باستخدام القيمة المقدَّمة في السمة name
(وليس اسم ملف XML). على هذا النحو، يمكنك دمج موارد مصفوفة السلاسل مع موارد أخرى بسيطة في ملف XML واحد ضمن عنصر <resources>
واحد.
- موقع الملف:
res/values/filename.xml
اسم الملف عشوائي. يتم استخدامname
للعنصر<string-array>
كرقم تعريف المورد.- نوع بيانات المورد المجمّع:
- مؤشر المورد إلى مصفوفة من
String
s. - مرجع للموارد:
-
في لغة 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>
- العناصر:
- مثلا:
- تم حفظ ملف 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()
لاختيار المورد المناسب لك.
على الرغم من أن سلاسل الكمية تُسمى في السابق "سلاسل الكمية" (ولا تزال تسمى ذلك في واجهة برمجة التطبيقات)، يجب استخدام سلاسل الكمية فقط لصيغ الجمع. سيكون من الخطأ استخدام سلاسل الكمية لتنفيذ
شيء مثل "البريد الوارد" في Gmail مقابل "البريد الوارد (12)" عندما تكون هناك رسائل غير مقروءة،
على سبيل المثال. قد يبدو من المناسب استخدام السلاسل الكمية بدلاً من عبارة if
،
لكن بعض اللغات (مثل الصينية) لا تستخدم هذه التناقضات النحوية على الإطلاق، لذلك ستحصل دائمًا على السلسلة other
.
يتم اختيار السلسلة المطلوب استخدامها بناءً على الضرورة النحوية فقط.
في اللغة الإنجليزية، يتم تجاهل سلسلة zero
حتى إذا كانت الكمية 0، لأنّ 0
لا يختلف نحويًا عن 2، أو أي رقم آخر باستثناء 1 ("صفر كتب" و"كتاب واحد"
و"كتابان" وما إلى ذلك). بالمقابل، في اللغة الكورية، يتم استخدام سلسلة other
فقط فقط.
ويجب عدم تضليل المستخدم من خلال أنّه، مثلاً، يبدو أنّ السمة two
تنطبق فقط على الكمية 2، فقد تتطلّب اللغة أن يتم التعامل مع الرقم 2 و12 و102 (وما إلى ذلك) بالطريقة نفسها، ولكن بطريقة مختلفة عن الكميات الأخرى. اعتمِد على المترجم للتعرُّف على الفروق
التي تبرزها لغتهم.
إذا لم تكن رسالتك تحتوي على رقم الكمية، فمن المحتمل أنها لا تتناسب مع صيغة الجمع. على سبيل المثال، في الليتوانية يتم استخدام صيغة المفرد لكل من 1 و101، لذلك تتم ترجمة "كتاب واحد" على النحو التالي "1 knyga"، بينما تتم ترجمة "101 كتاب" على أنها "101 knyga". في حين أن "الكتاب" هو "knyga" و "العديد من الكتب" هو "daug knyg مشاهدي". إذا كانت رسالة الجمع باللغة الإنجليزية تحتوي على "كتاب" (مفرد) و "عدّة كتب" بدون العدد الفعلي، يمكن ترجمتها على أنّها "knyga" (كتاب)/"daug knyg مشاهدي" (العديد من الكتب)، ولكن وفقًا للقواعد الليتوانية، ستعرض العبارة "knyga" (كتاب واحد) عندما يكون العدد 101.
غالبًا ما يكون من الممكن تجنب السلاسل الكمية باستخدام صيغ محايدة كمية مثل "الكتب: 1". وهذا يجعل حياتك وحياة المترجمين أسهل إذا كان أسلوبًا مقبولاً للطلب.
في واجهة برمجة التطبيقات 24 والإصدارات الأحدث، يمكنك استخدام فئة MessageFormat
لوحدة ICU
الأكثر فعالية بدلاً من ذلك.
ملاحظة: مجموعة صيغ الجمع هي مورد بسيط تتم الإشارة إليه باستخدام القيمة المقدّمة في السمة name
(وليس اسم ملف XML). وبناءً على ذلك، يمكنك دمج موارد صيغ الجمع مع موارد أخرى بسيطة في ملف XML واحد ضمن عنصر <resources>
واحد.
- موقع الملف:
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>
- العناصر:
- مثلا:
- تم حفظ ملف 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
.
التنسيق والنمط
فيما يلي بعض الأشياء المهمة التي يجب أن تعرفها حول كيفية تنسيق موارد السلسلة وتصميمها بشكل صحيح.
التعامل مع الرموز الخاصة
عندما تحتوي السلسلة على أحرف لها استخدام خاص في XML، عليك إلغاء هذه الأحرف وفقًا لقواعد الهروب العادية بتنسيق XML/HTML. وإذا كنت بحاجة إلى إلغاء حرف له معنى خاص في نظام Android، عليك استخدام شرطة مائلة للخلف.
سيصغّر Android تلقائيًا تسلسلات أحرف المسافات البيضاء في مساحة واحدة. يمكنك تجنب ذلك عن طريق تضمين الجزء ذي الصلة من السلسلة بين علامتي اقتباس. وفي هذه الحالة، سيتم الاحتفاظ بجميع أحرف المسافات البيضاء (بما في ذلك الأسطر الجديدة) داخل المنطقة المذكورة. تتيح لك علامات الاقتباس المزدوجة أيضًا استخدام علامات الاقتباس المفردة العادية التي لا يتم تجاوزها.
حرف | النماذج التي تم الخروج منها |
---|---|
@ | \@ |
؟ | \? |
سطر جديد | \n |
Tab | \t |
حرف يونيكود U+XXXX | \uXXXX |
علامة الاقتباس المفردة (' ) |
أيّ ممّا يلي:
|
علامة الاقتباس المزدوجة (" ) |
\"
لاحظ أن إحاطة السلسلة بعلامات اقتباس مفردة لا يعمل. |
يحدث تصغير المسافات البيضاء وإنهاء عمل Android بعد تحليل ملف المورد كملف XML. وهذا يعني أنّه يمكن تصغير <string>      </string>
(مسافة، مسافة علامات الترقيم، مسافة Unicode Em) إلى مسافة واحدة (" "
)، لأنّها كلها مساحات Unicode بعد تحليل الملف كملف XML.
للحفاظ على هذه المساحات كما هي، يمكنك إما اقتباسها
(<string>"      "</string>
)
أو استخدام رمز الإلغاء في Android
(<string> \u0032 \u8200 \u8195</string>
).
ملاحظة: من منظور محلّل XML، ما مِن اختلاف بين
<string>"Test this"</string>
و<string>"Test this"</string>
من أي نوع. ولن يعرض كلا النموذجين أي علامات اقتباس، بل يؤديان إلى تشغيل علامات اقتباس مع الحفاظ على المسافات في Android (ولن يكون لذلك أي تأثير عملي في هذه الحالة).
تنسيق السلاسل
إذا كنت بحاجة إلى تنسيق السلاسل الخاصة بك، فيمكنك القيام بذلك عن طريق وضع وسيطات التنسيق الخاصة بك في مورد السلسلة، كما هو موضح في المثال التالي للمورد.
<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>
يمكن استخدام عناصر HTML التالية:
- غامق: <b>
- مائل: <i>، <cite>، <dfn>، <em>
- نص أكبر بنسبة 25%: <big>
- نص أصغر بنسبة% 20: <صغير>
- ضبط خصائص الخطوط: <font face=”font_family“ color=”hex_color”>. تتضمن أمثلة
مجموعات الخطوط المحتملة
monospace
وserif
وsans_serif
. - إعداد عائلة خطوط أحادي المسافة: <tt>
- نص يتوسّطه خط: <s>، <strike>، <del>
- تسطير: <u>
- مرتفع: <sup>
- منخفض: <sub>
- الرموز النقطية: <ul>، <li>
- فواصل الأسطر: <br>
- القسم: <div>
- نمط CSS: <span style=”color|background_color|text-decoration”>
- الفقرات: <p dir=”rtl | ltr” style=”...”>
إذا لم تكن تطبّق التنسيق، يمكنك ضبط نص TextView مباشرةً من خلال طلب
setText(java.lang.CharSequence)
. ومع ذلك، قد تحتاج في بعض الحالات
إلى إنشاء مورد نصي بنمط معيّن يتم استخدامه أيضًا كسلسلة تنسيق. في العادة، لا تنجح هذه الطريقة لأنّ الطريقتين format(String, Object...)
وgetString(int, Object...)
تزيلان جميع معلومات النمط من السلسلة. والحل البديل لذلك هو كتابة علامات HTML باستخدام الكيانات التي تم تخطيها، والتي يتم استردادها بعد ذلك باستخدام fromHtml(String)
، بعد حدوث التنسيق. مثلاً:
- تخزين المورد النصي ذو النمط كسلسلة HTML تتضمن أحرف إلغاء:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
في هذه السلسلة المنسّقة، تمت إضافة عنصر
<b>
. لاحظ أنّ القوس الافتتاحي يتضمّن أحرف إلغاء HTML، وذلك باستخدام علامة<
. - بعد ذلك، نسِّق السلسلة كالمعتاد، ولكن استدعِ
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>
في ملفات موارد shortcuts.xml. وتتيح لك علامة التعليق التوضيحي
وضع علامة على أجزاء من السلسلة لتنسيق مخصّص من خلال تحديد أزواج المفتاح/القيمة المخصّصة في ملف XML
الذي يحوّله إطار العمل بعد ذلك إلى مساحات Annotation
. يمكنك بعد ذلك استرداد هذه التعليقات التوضيحية واستخدام المفتاح والقيمة لتطبيق النمط.
عند إنشاء تعليقات توضيحية، احرص على إضافة العلامة <annotation>
إلى جميع ترجمات السلسلة في كل ملف shortcuts.xml.
تطبيق خط طباعي مخصّص على كلمة "نص" في جميع اللغات
مثال - إضافة خط طباعي مخصص
-
أضف العلامة
<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>
-
حمِّل مورد السلسلة وابحث عن التعليقات التوضيحية باستخدام مفتاح الخط. بعد ذلك، يمكنك إنشاء مدى مخصّص واستبدال النطاق الحالي.
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);
لمزيد من المعلومات عن نمط النص، اطّلع على الروابط التالية: