На этой странице описано, как установить шрифты в приложении Compose.
Установить шрифт
Text
имеет параметр fontFamily
, позволяющий установить шрифт, используемый в составном элементе. По умолчанию включены семейства шрифтов с засечками, без засечек, моноширинные и курсивные:
@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.7.3" }
Котлин
dependencies { ... implementation("androidx.compose.ui:ui-text-google-fonts:1.7.3") }
- Инициализируйте
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:
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!") } }
Предостережения
Google Fonts требуется несколько месяцев, чтобы сделать новые шрифты доступными на Android. Существует разрыв во времени между добавлением шрифта на 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), ) ) )
API
FontVariation
позволяет настраивать стандартные оси шрифта, такие как вес , ширина и наклон . Это стандартные оси, доступные с любым изменяемым шрифтом. Вы можете создавать различные конфигурации шрифта в зависимости от того, где он будет использоваться.Переменные шрифты доступны только для версий 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
настраивается с помощью стиля темы материала и содержит различную конфигурацию изменяемого шрифта. Вы можете использовать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