На этой странице рассказывается, как задавать шрифты в приложении Compose.
Как задать шрифт
Text имеет параметр fontFamily, позволяющий задать шрифт, используемый в composable-функции. По умолчанию семейства шрифтов с засечками, без засечек, моноширинные и рукописные включены:
@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 в composable-функцию 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 скачиваемых шрифтов, чтобы асинхронно скачивать шрифты Google и использовать их в приложении.
В настоящее время поддержка скачиваемых шрифтов, предоставленных сторонними поставщиками, недоступна.
Как использовать скачиваемые шрифты программно
Чтобы скачать шрифт программным способом из приложения, выполните следующие действия:
- Добавьте зависимость:
Яркий
dependencies { ... implementation "androidx.compose.ui:ui-text-google-fonts:1.12.1" }
Kotlin
dependencies { ... implementation("androidx.compose.ui:ui-text-google-fonts:1.12.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, который будет использоваться в composable-функции Text:
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.
Отладка реализации
Чтобы проверить, правильно ли скачивается шрифт, можно определить обработчик сопрограммы отладки. Ваш дескриптор определяет, что делать, если шрифт не загрузится асинхронно.
Начните с создания 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 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), ) ) )
FontVariationAPI позволяет настраивать стандартные оси шрифта, такие как weight, width и slant. Это стандартные оси, доступные для любого вариативного шрифта. Вы можете создавать разные конфигурации шрифта в зависимости от того, где он будет использоваться.Переменные шрифты доступны только в 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 )
Наконец, используйте composable-функцию
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 ) } } } }
Каждая composable-функция
Textнастраивается с помощью стиля темы Material Design и содержит собственную конфигурацию переменного шрифта. Вы можете использоватьMaterialTheme.typography, чтобы получить типографику, предоставленную composable-функции 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