בדף הזה מוסבר איך להגדיר גופנים באפליקציית Compose.
הגדרת גופן
Text
יש פרמטר fontFamily
שמאפשר להגדיר את הגופן שבו משתמשים ב-composable. כברירת מחדל, משפחות הגופנים serif, sans-serif, monospace ו-cursive כלולות:
@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, אפשר להשתמש בממשק ה-API של גופנים להורדה באפליקציית Compose כדי להוריד גופנים של Google באופן אסינכרוני ולהשתמש בהם באפליקציה.
בשלב הזה אין תמיכה בגופנים להורדה שסופקו על ידי ספקים בהתאמה אישית.
שימוש בגופנים להורדה באופן פרוגרמטי
כדי להוריד גופן באופן פרוגרמטי מתוך האפליקציה:
- מוסיפים את יחסי התלות:
מגניב
dependencies { ... implementation "androidx.compose.ui:ui-text-google-fonts:1.8.1" }
Kotlin
dependencies { ... implementation("androidx.compose.ui:ui-text-google-fonts:1.8.1") }
- מאתחלים את
GoogleFont.Provider
עם פרטי הכניסה לגופנים של Google: הפרמטרים שהספק מקבל הם: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.
- חבילת ספק הגופנים לאימות הזהות של הספק.
- רשימה של קבוצות גיבוב לאימות הזהות של הספק. אפשר למצוא את הגיבובים שנדרשים לספק 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 composable:
Text( fontFamily = fontFamily, text = "Hello World!" )

אפשר גם להגדיר טיפוגרפיה לשימוש בFontFamily
:
val MyTypography = Typography( bodyMedium = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Normal, fontSize = 12.sp/*...*/ ), bodyLarge = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Bold, letterSpacing = 2.sp, /*...*/ ), headlineMedium = 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
.
ניפוי באגים בהטמעה
כדי לוודא שהגופן מורד בצורה תקינה, אפשר להגדיר handler של קורוטינה לניפוי באגים. הכינוי מספק את ההתנהגות של מה לעשות במקרה שהגופן לא נטען באופן אסינכרוני.
קודם כול צריך ליצור 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 ) } }
אפשר גם להשתמש ב-API של הספק isAvailableOnDevice
כדי לבדוק אם הספק זמין והאישורים מוגדרים בצורה נכונה. כדי לעשות את זה, אפשר לקרוא לשיטה isAvailableOnDevice
שמחזירה false אם הספק מוגדר בצורה לא נכונה.
val context = LocalContext.current LaunchedEffect(Unit) { if (provider.isAvailableOnDevice(context)) { Log.d(TAG, "Success!") } }
נקודות שחשוב לדעת
לוקח כמה חודשים עד שגופנים חדשים יהיו זמינים ב-Android דרך Google Fonts.
יש פער זמן בין הרגע שבו גופן מתווסף ל-fonts.google.com לבין הרגע שבו הוא זמין דרך ה-API של גופנים להורדה (במערכת View או ב-Compose). יכול להיות שהגופנים החדשים שנוספו לא ייטענו באפליקציה עם השגיאה IllegalStateException
.
כדי לעזור למפתחים לזהות את השגיאה הזו מבין סוגים אחרים של שגיאות בטעינת גופנים, הוספנו הודעה תיאורית לחריגה ב-Compose עם השינויים שמופיעים כאן.
אם נתקלים בבעיות, אפשר לדווח עליהן באמצעות הכלי למעקב אחר בעיות.
שימוש בגופנים משתנים
גופן משתנה הוא פורמט גופן שמאפשר לקובץ גופן אחד להכיל סגנונות שונים. בעזרת גופנים משתנים, אתם יכולים לשנות צירים (או פרמטרים) כדי ליצור את הסגנון המועדף עליכם. הצירים האלה יכולים להיות סטנדרטיים, כמו משקל, רוחב, הטיה וכתב נטוי, או מותאמים אישית, שמשתנים בין גופנים משתנים.

שימוש בגופנים משתנים במקום בקובצי גופנים רגילים מאפשר לכם להשתמש רק בקובץ גופן אחד במקום בכמה קבצים.
כדי לקבל מידע נוסף על גופנים משתנים, אפשר לעיין במאגר הידע של Google Fonts, בקטלוג המלא של גופנים משתנים זמינים ובטבלה של הצירים הנתמכים לכל גופן.
במסמך הזה מוסבר איך להטמיע גופן משתנה באפליקציית 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
API מאפשר להגדיר צירים סטנדרטיים של גופנים, כמו משקל, רוחב ושיפוע. אלה צירים רגילים שזמינים בכל גופן משתנה. אתם יכולים ליצור הגדרות שונות של הגופן בהתאם למקום שבו הוא ישמש.גופנים משתנים זמינים רק ב-Android מגרסה O ואילך, לכן צריך להוסיף אמצעי הגנה ולהגדיר חלופה מתאימה:
// 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 }
מגדירים את הטיפוגרפיה של Material Design 3 כך שתשתמש ב-
FontFamily
:// Type.kt val Typography = Typography( displayLarge = TextStyle( fontFamily = displayLargeFontFamily, fontSize = 50.sp, lineHeight = 64.sp, letterSpacing = 0.sp, /***/ ) )
בדוגמה הזו נעשה שימוש ב
displayLarge
טיפוגרפיה של Material 3, שכוללת הגדרות שונות של גופן ברירת המחדל ושימושים מומלצים. לדוגמה, כדאי להשתמש ב-displayLarge
לטקסט קצר וחשוב, כי זה הטקסט הכי גדול במסך.ב-Material 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
ניתן להגדרה באמצעות הסגנון של ערכת העיצוב Material שלו, והוא מכיל הגדרת גופן משתנה שונה. אפשר להשתמש ב-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