توضّح هذه الصفحة كيفية ضبط الخطوط في تطبيق Compose.
ضبط الخط
يحتوي Text
على معلَمة fontFamily
للسماح بضبط الخط المستخدَم في العنصر القابل للإنشاء. بشكل تلقائي، يتم تضمين مجموعات الخطوط serif وsans-serif و أحادي المسافة والخطوط المنحنية:
@Composable fun DifferentFonts() { Column { Text("Hello World", fontFamily = FontFamily.Serif) Text("Hello World", fontFamily = FontFamily.SansSerif) } }
يمكنك استخدام السمة fontFamily
للعمل على الخطوط والخطوط الطباعية المخصّصة
المحددة في مجلد res/font
:
يوضّح هذا المثال كيفية تحديد fontFamily
استنادًا إلى ملفات الخطوط هذه واستخدام الدالة Font
:
val firaSansFamily = FontFamily( Font(R.font.firasans_light, FontWeight.Light), Font(R.font.firasans_regular, FontWeight.Normal), Font(R.font.firasans_italic, FontWeight.Normal, FontStyle.Italic), Font(R.font.firasans_medium, FontWeight.Medium), Font(R.font.firasans_bold, FontWeight.Bold) )
يمكنك تمرير هذا fontFamily
إلى Text
القابل للإنشاء. بما أنّ السمة fontFamily
يمكن أن تتضمّن أوزانًا مختلفة، يمكنك ضبط fontWeight
يدويًا لاختيار الوزن المناسب للنص:
Column { Text(text = "text", fontFamily = firaSansFamily, fontWeight = FontWeight.Light) Text(text = "text", fontFamily = firaSansFamily, fontWeight = FontWeight.Normal) Text( text = "text", fontFamily = firaSansFamily, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Italic ) Text(text = "text", fontFamily = firaSansFamily, fontWeight = FontWeight.Medium) Text(text = "text", fontFamily = firaSansFamily, fontWeight = FontWeight.Bold) }
للتعرّف على كيفية ضبط أسلوب الخط في تطبيقك بالكامل، يُرجى الاطّلاع على أنظمة التصميم المخصّصة في Compose.
الخطوط القابلة للتنزيل
بدءًا من Compose 1.2.0، يمكنك استخدام واجهة برمجة تطبيقات الخطوط القابلة للتنزيل في تطبيق Compose لتنزيل خطوط Google بشكلٍ غير متزامن واستخدامها في تطبيقك.
لا تتوفّر حاليًا إمكانية استخدام الخطوط القابلة للتنزيل التي يقدّمها مزوّدو الخدمة المخصّصون.
استخدام الخطوط القابلة للتنزيل آليًا
لتنزيل خط آليًا من داخل تطبيقك، اتبع الخطوات التالية:
- أضف التبعية:
رائع
dependencies { ... implementation "androidx.compose.ui:ui-text-google-fonts:1.6.1" }
Kotlin
dependencies { ... implementation("androidx.compose.ui:ui-text-google-fonts:1.6.1") }
- عليك إعداد
GoogleFont.Provider
باستخدام بيانات اعتماد Google Fonts:val provider = GoogleFont.Provider( providerAuthority = "com.google.android.gms.fonts", providerPackage = "com.google.android.gms", certificates = R.array.com_google_android_gms_fonts_certs )
المعلَمات التي يتلقّاها مقدّم الخدمة هي:- مرجع موفّر الخطوط لخطوط Google Fonts
- حزمة موفِّر الخط للتحقّق من هوية موفِّر الخطوط.
- قائمة بمجموعات تجزئات الشهادات للتحقّق من هوية مقدّم الخدمة. يمكنك العثور على علامات التجزئة المطلوبة لموفّر خدمة Google Fonts في ملف
font_certs.xml
في نموذج تطبيق Jetchat.
- تحديد
FontFamily
:// ... import androidx.compose.ui.text.googlefonts.GoogleFont import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.googlefonts.Font // ... val fontName = GoogleFont("Lobster Two") val fontFamily = FontFamily( Font(googleFont = fontName, fontProvider = provider) )
يمكنك الاستعلام عن معلَمات أخرى للخط، مثل الوزن والنمط باستخدامFontWeight
وFontStyle
على التوالي:// ... import androidx.compose.ui.text.googlefonts.GoogleFont import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.googlefonts.Font // ... val fontName = GoogleFont("Lobster Two") val fontFamily = FontFamily( Font( googleFont = fontName, fontProvider = provider, weight = FontWeight.Bold, style = FontStyle.Italic ) )
- اضبط
FontFamily
لاستخدامه في الدالة القابلة للإنشاء النصية:
Text( fontFamily = fontFamily, text = "Hello World!" )
يمكنك أيضًا تعريف أسلوب الخط لاستخدام FontFamily
:
val MyTypography = Typography( labelMedium = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Normal, fontSize = 12.sp/*...*/ ), labelLarge = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Bold, letterSpacing = 2.sp, /*...*/ ), displayMedium = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.SemiBold/*...*/ ), /*...*/ )
بعد ذلك، اضبط أسلوب الخط على مظهر تطبيقك:
MyAppTheme( typography = MyTypography )/*...*/
للحصول على مثال على تطبيق ينفّذ خطوطًا قابلة للتنزيل في Compose جنبًا إلى جنب مع Material3، يُرجى الاطّلاع على نموذج تطبيق Jetchat.
إضافة خطوط احتياطية
يمكنك تحديد سلسلة من العناصر الاحتياطية للخط في حال تعذّر تنزيل الخط بشكل صحيح. على سبيل المثال، إذا كان الخط القابل للتنزيل لديك محدد على النحو التالي:
// ... import androidx.compose.ui.text.googlefonts.Font // ... val fontName = GoogleFont("Lobster Two") val fontFamily = FontFamily( Font(googleFont = fontName, fontProvider = provider), Font(googleFont = fontName, fontProvider = provider, weight = FontWeight.Bold) )
ويمكنك تحديد الإعدادات الافتراضية للخط لكل من معاملات الترجيح على النحو التالي:
// ... import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.googlefonts.Font // ... val fontName = GoogleFont("Lobster Two") val fontFamily = FontFamily( Font(googleFont = fontName, fontProvider = provider), Font(resId = R.font.my_font_regular), Font(googleFont = fontName, fontProvider = provider, weight = FontWeight.Bold), Font(resId = R.font.my_font_regular_bold, weight = FontWeight.Bold) )
تأكَّد من إضافة عمليات الاستيراد الصحيحة.
يؤدّي تحديد FontFamily
على هذا النحو إلى إنشاء FontFamily
تحتوي على سلسلتَين، واحدة لكل وزن. ستحاول آلية التحميل مطابقة الخط المتوفر على الإنترنت أولاً،
ثم إصلاح الخط في مجلد موارد R.font
المحلي.
تصحيح الأخطاء في عملية التنفيذ
لمساعدتك في التحقق مما إذا تم تنزيل الخط بشكل صحيح، يمكنك تحديد معالج تصحيح أخطاء الكوروتين. يوفر مؤشرك سلوك ما يجب فعله في حالة فشل تحميل الخط بشكل غير متزامن.
ابدأ بإنشاء CoroutineExceptionHandler
:
val handler = CoroutineExceptionHandler { _, throwable -> // process the Throwable Log.e(TAG, "There has been an issue: ", throwable) }
مرِّره إلى الطريقة
createFontFamilyResolver
لجعل برنامج التعيين يستخدم المعالج الجديد:
CompositionLocalProvider( LocalFontFamilyResolver provides createFontFamilyResolver(LocalContext.current, handler) ) { Column { Text( text = "Hello World!", style = MaterialTheme.typography.bodyMedium ) } }
يمكنك أيضًا استخدام واجهة برمجة التطبيقات
isAvailableOnDevice
من مقدّم الخدمة لاختبار ما إذا كان الموفِّر متاحًا ومن ضبط الشهادات
بشكل صحيح. للقيام بذلك، يمكنك استدعاء الطريقة isAvailableOnDevice
التي تعرض خطأ إذا تم ضبط الموفر بشكل غير صحيح.
val context = LocalContext.current LaunchedEffect(Unit) { if (provider.isAvailableOnDevice(context)) { Log.d(TAG, "Success!") } }
محاذير
يستغرق تطبيق Google Fonts عدة أشهر لإتاحة خطوط جديدة على Android.
هناك فاصل زمني بين وقت إضافة خط في fonts.google.com ووقت توفّره من خلال واجهة Font API القابلة للتنزيل (إما في نظام العرض أو في Compose). قد يتعذّر تحميل الخطوط المُضافة حديثًا في تطبيقك من خلال إضافة IllegalStateException
.
لمساعدة المطوّرين في التعرّف على هذا الخطأ في الأنواع الأخرى من أخطاء تحميل الخطوط، أضفنا رسائل وصفية للاستثناء في Compose مع التغييرات هنا.
إذا عثرت على أي مشاكل، يمكنك الإبلاغ عنها باستخدام أداة تتبّع المشاكل.
استخدام خطوط متغيرة
الخط المتغير هو تنسيق خط يسمح لملف خط واحد باحتواء أنماط مختلفة. باستخدام الخطوط المتغيرة، يمكنك تعديل المحاور (أو المعلمات) لإنشاء نمطك المفضل. يمكن أن تكون هذه المحاور قياسية، مثل الوزن والعرض والمائل والمائل أو المخصصة، والتي تختلف عبر الخطوط المتغيرة.
إنّ استخدام الخطوط المتغيّرة بدلاً من ملفات الخطوط العادية يتيح لك استخدام ملف خط واحد فقط بدلاً من ملفات خط متعددة.
للحصول على مزيد من التفاصيل العامة حول الخطوط المتغيّرة، يُرجى الاطّلاع على مقالة Google Fonts Knowledge والكتالوج الكامل للخطوط المتغيّرة المتاحة وجدول بالمحاور المتوافقة لكل خط.
يوضح لك هذا المستند كيفية تنفيذ خط متغيّر في تطبيق Compose.
تحميل خط متغيّر
نزِّل الخط المتغيّر الذي تريد استخدامه (على سبيل المثال Roboto Flex) وضَعه في المجلد
app/res/font
في تطبيقك. تأكّد من أنّttf
يكون ملف الخط الذي تضيفه هو إصدار الخط المتغير للخط، وأن يكون اسم الملف بأحرف صغيرة ولا يحتوي على أي رموز خاصة.لتحميل خط متغيّر، حدِّد
FontFamily
باستخدام الخط المتوفّر في دليلres/font/
:// In Typography.kt @OptIn(ExperimentalTextApi::class) val displayLargeFontFamily = FontFamily( Font( R.font.robotoflex_variable, variationSettings = FontVariation.Settings( FontVariation.weight(950), FontVariation.width(30f), FontVariation.slant(-6f), ) ) )
تتيح لك واجهة برمجة التطبيقات
FontVariation
ضبط محاور الخطوط العادية، مثل الوزن والعرض والمائل. هذه هي المحاور القياسية المتوفرة مع أي خط متغير. يمكنك إنشاء تكوينات مختلفة للخط بناءً على مكان استخدام الخط.لا تتوفّر الخطوط المتغيّرة إلا للإصدار O والإصدارات الأحدث من نظام التشغيل Android، لذا عليك إضافة شريط حماية وإعداد خط احتياطي مناسب:
// In Typography.kt val default = FontFamily( /* * This can be any font that makes sense */ Font( R.font.robotoflex_static_regular ) ) @OptIn(ExperimentalTextApi::class) val displayLargeFontFamily = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { FontFamily( Font( R.font.robotoflex_variable, variationSettings = FontVariation.Settings( FontVariation.weight(950), FontVariation.width(30f), FontVariation.slant(-6f), ) ) ) } else { default }
استخرِج الإعدادات في مجموعة من الثوابت لتسهيل إعادة استخدامها واستبدل إعدادات الخط بهذه الثوابت:
// VariableFontDimension.kt object DisplayLargeVFConfig { const val WEIGHT = 950 const val WIDTH = 30f const val SLANT = -6f const val ASCENDER_HEIGHT = 800f const val COUNTER_WIDTH = 500 } @OptIn(ExperimentalTextApi::class) val displayLargeFontFamily = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { FontFamily( Font( R.font.robotoflex_variable, variationSettings = FontVariation.Settings( FontVariation.weight(DisplayLargeVFConfig.WEIGHT), FontVariation.width(DisplayLargeVFConfig.WIDTH), FontVariation.slant(DisplayLargeVFConfig.SLANT), ) ) ) } else { default }
ضبط أسلوب الخط في التصميم المتعدد الأبعاد لاستخدام
FontFamily
:// Type.kt val Typography = Typography( displayLarge = TextStyle( fontFamily = displayLargeFontFamily, fontSize = 50.sp, lineHeight = 64.sp, letterSpacing = 0.sp, /***/ ) )
يستخدم هذا النموذج
displayLarge
أسلوب الخط في الإصدار 3 الذي يشمل إعدادات خط تلقائية مختلفة واستخدامات مُقترَحة. على سبيل المثال، يجب استخدامdisplayLarge
للإشارة إلى نص قصير قيّم، لأنّه النص الأكبر على الشاشة.باستخدام المادة 3، يمكنك تغيير القيم التلقائية لكل من
TextStyle
وfontFamily
لتخصيص أسلوب الخط. في المقتطف أعلاه، يمكنك ضبط مثيلاتTextStyle
لتخصيص إعدادات الخط لكل مجموعة خطوط.الآن بعد أن حددت أسلوب الخط، مرِّره إلى M3
MaterialTheme
:MaterialTheme( colorScheme = MaterialTheme.colorScheme, typography = Typography, content = content )
وأخيرًا، استخدِم عنصر
Text
قابلاً للإنشاء وحدِّد النمط لأحد أنماط الطباعة المحدّدة،MaterialTheme.typography.displayLarge
:@Composable @Preview fun CardDetails() { MyCustomTheme { Card( shape = RoundedCornerShape(8.dp), elevation = CardDefaults.cardElevation(defaultElevation = 4.dp), modifier = Modifier .fillMaxWidth() .padding(16.dp) ) { Column( modifier = Modifier.padding(16.dp) ) { Text( text = "Compose", style = MaterialTheme.typography.displayLarge, modifier = Modifier.padding(bottom = 8.dp), maxLines = 1 ) Text( text = "Beautiful UIs on Android", style = MaterialTheme.typography.headlineMedium, modifier = Modifier.padding(bottom = 8.dp), maxLines = 2 ) Text( text = "Jetpack Compose is Android’s recommended modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs.", style = MaterialTheme.typography.bodyLarge, modifier = Modifier.padding(bottom = 8.dp), maxLines = 3 ) } } } }
يتم إعداد كل
Text
قابل للإنشاء من خلال نمط "المظهر المتعدد الأبعاد"، ويحتوي على إعدادات خط متغيّر مختلفة. يمكنك استخدامMaterialTheme.typography
لاسترداد أسلوب الخط المتوفّر في عنصر M3MaterialTheme
القابل للإنشاء.
استخدام محاور مخصّصة
يمكن أن يكون للخطوط أيضًا محاور مخصّصة. ويتم تحديدها داخل ملف الخط نفسه.
على سبيل المثال، يحتوي خط Roboto Flex على محور الصاعد ("YTAS"
)، الذي يضبط ارتفاع الصاعدات الصغيرة، بينما يضبط عرض العدّاد ("XTRA"
) عرض كل حرف.
يمكنك تغيير قيمة هذه المحاور باستخدام إعدادات FontVariation
.
لمزيد من المعلومات عن المحاور المخصّصة التي يمكنك إعدادها لخط، اطّلِع على جدول المحاور المتوافقة لكل خط.
لاستخدام محاور مخصّصة، حدّد دوال للمحورَين المخصّصَين
ascenderHeight
وcounterWidth
:fun ascenderHeight(ascenderHeight: Float): FontVariation.Setting { require(ascenderHeight in 649f..854f) { "'Ascender Height' must be in 649f..854f" } return FontVariation.Setting("YTAS", ascenderHeight) } fun counterWidth(counterWidth: Int): FontVariation.Setting { require(counterWidth in 323..603) { "'Counter width' must be in 323..603" } return FontVariation.Setting("XTRA", counterWidth.toFloat()) }
وتؤدي هذه الدوال ما يلي:
- ضَع بعض القيود على القيم التي يمكن قبولها. كما ترى في كتالوج الخطوط المتغيّرة، إنّ قيمة
ascenderHeight (YTAS)
هي649f
كحدّ أدنى و854f
كحدّ أقصى. - اعرض إعداد الخط، لذا تكون الإعدادات جاهزة للإضافة إلى الخط. في الطريقة
FontVariation.Setting()
، يكون اسم المحور (YTAS, XTRA
) برمجيًا بشكل كامل، ويأخذ القيمة كمَعلمة.
- ضَع بعض القيود على القيم التي يمكن قبولها. كما ترى في كتالوج الخطوط المتغيّرة، إنّ قيمة
باستخدام المحاور مع ضبط الخط، مرِّر معلَمات إضافية إلى كل
Font
يتم تحميلها:@OptIn(ExperimentalTextApi::class) val displayLargeFontFamily = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { FontFamily( Font( R.font.robotoflex_variable, variationSettings = FontVariation.Settings( FontVariation.weight(DisplayLargeVFConfig.WEIGHT), FontVariation.width(DisplayLargeVFConfig.WIDTH), FontVariation.slant(DisplayLargeVFConfig.SLANT), ascenderHeight(DisplayLargeVFConfig.ASCENDER_HEIGHT), counterWidth(DisplayLargeVFConfig.COUNTER_WIDTH) ) ) ) } else { default }
لاحظ أن ارتفاع الأحرف الصاعدة الصغيرة يزداد الآن، والنص الآخر أوسع:
مراجع إضافية
لمزيد من المعلومات، راجع مشاركة المدونة التالية حول الخطوط المتغيرة:
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عند إيقاف JavaScript.
- الموارد في Compose
- تحديد نمط النص
- Material Design 2 في Compose