Praca z czcionkami

Na tej stronie dowiesz się, jak ustawić czcionki w aplikacji Utwórz.

Ustaw czcionkę

Text ma parametr fontFamily, który umożliwia ustawienie czcionki używanej w kompozycyjne. Domyślnie rodziny czcionek szeryfowych, bezszeryfowych, o stałej szerokości i kursywy. są uwzględniane:

@Composable
fun DifferentFonts() {
    Column {
        Text("Hello World", fontFamily = FontFamily.Serif)
        Text("Hello World", fontFamily = FontFamily.SansSerif)
    }
}

Słowa

Możesz użyć atrybutu fontFamily, aby pracować z niestandardowymi czcionkami i krojami czcionki zdefiniowano w folderze res/font:

Graficzne przedstawienie rozdzielczości > folder font w środowisku programistycznym

Ten przykład pokazuje, jak można zdefiniować pole fontFamily na podstawie tych czcionek za pomocą funkcji 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)
)

Możesz przekazać ten element (fontFamily) do funkcji kompozycyjnej Text. Ponieważ Parametr fontFamily może obejmować różne wagi. Możesz ręcznie ustawić wartość fontWeight na wybrać odpowiednią wagę dla tekstu:

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)
}

Słowa

Więcej informacji o ustawianiu typografii w całej aplikacji znajdziesz w artykule Niestandardowe systemy projektowania w usłudze Compose.

Czcionki do pobrania

Uruchamiam w widoku Utwórz 1.2.0, możesz pobrać interfejs API czcionek do pobrania w aplikacji Compose, aby pobrać Google asynchronicznie i używać ich w aplikacji.

Czcionki do pobrania dostarczane przez dostawców niestandardowych nie są obecnie obsługiwane.

Automatyczne korzystanie z czcionek, które można pobrać

Aby pobrać czcionkę automatycznie z aplikacji, wykonaj te czynności:

  1. Dodaj zależność:

    Odlotowe

    dependencies {
        ...
        implementation "androidx.compose.ui:ui-text-google-fonts:1.6.8"
    }
    

    Kotlin

    dependencies {
        ...
        implementation("androidx.compose.ui:ui-text-google-fonts:1.6.8")
    }
  2. Zainicjuj GoogleFont.Provider danymi logowania do 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
    )
    Dostawca otrzymuje te parametry:
    • Urząd dostawcy czcionek Google Fonts.
    • Pakiet dostawcy czcionek do weryfikacji tożsamości dostawcy.
    • Lista zestawów haszy dla certyfikatów umożliwiających weryfikację tożsamości dostawcy usług. Znajdziesz tam hasze wymagane przez dostawcę Google Fonts w pliku font_certs.xml w Przykładowa aplikacja Jetchat.
  3. Zdefiniuj 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)
    )
    Możesz też wysyłać zapytania o inne parametry czcionki, takie jak waga i styl, FontWeight oraz 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
        )
    )
  4. Skonfiguruj FontFamily tak, aby używane w funkcji tworzenia tekstu.

Text(
    fontFamily = fontFamily, text = "Hello World!"
)

Możesz także określić Typografia, której należy użyć 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/*...*/
    ),
    /*...*/
)

Następnie ustaw typografię na motyw aplikacji:

MyAppTheme(
    typography = MyTypography
)/*...*/

Przykład aplikacji, która implementuje czcionki do pobrania w funkcji Compose w połączeniu z elementami Material3, zobacz przykładową aplikację Jetchat.

Dodawanie czcionek zastępczych

Możesz określić łańcuch kreacji zastępczych dla czcionki, jeśli czcionka się nie powiedzie. pobierz poprawnie. Jeśli na przykład masz zdefiniowaną czcionkę do pobrania podobny do tego:

// ...
 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)
)

Możesz w ten sposób zdefiniować wartości domyślne czcionki dla obu tych grubości:

// ...
 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)
)

Sprawdź, czy importujesz właściwe dane.

Zdefiniowanie w ten sposób elementu FontFamily powoduje utworzenie elementu FontFamily zawierającego 2 łańcuchy, jeden na wagę. Mechanizm wczytywania najpierw spróbuje rozpoznać czcionkę online, oraz czcionkę z lokalnego folderu zasobów R.font.

Debugowanie implementacji

Aby sprawdzić, czy czcionka jest pobierana prawidłowo, możesz zdefiniować modułu obsługi współpracy na potrzeby debugowania. Nick określa działanie, jakie możesz wykonać w przypadku czcionka nie wczytuje się asynchronicznie.

Zacznij od utworzenia CoroutineExceptionHandler:

val handler = CoroutineExceptionHandler { _, throwable ->
    // process the Throwable
    Log.e(TAG, "There has been an issue: ", throwable)
}

Przekaż ją do createFontFamilyResolver aby resolver używał nowego modułu obsługi:

CompositionLocalProvider(
    LocalFontFamilyResolver provides createFontFamilyResolver(LocalContext.current, handler)
) {
    Column {
        Text(
            text = "Hello World!", style = MaterialTheme.typography.bodyMedium
        )
    }
}

Możesz też użyć usługi isAvailableOnDevice interfejs API od dostawcy do sprawdzenia, czy dostawca jest dostępny, a certyfikaty poprawnie skonfigurowane. Aby to zrobić, możesz wywołać metodę isAvailableOnDevice zwracający wartość „false”, jeśli dostawca jest nieprawidłowo skonfigurowany.

val context = LocalContext.current
LaunchedEffect(Unit) {
    if (provider.isAvailableOnDevice(context)) {
        Log.d(TAG, "Success!")
    }
}

Uwagi

Google Fonts ma kilka miesięcy, by udostępnić nowe czcionki na Androida. Po dodaniu czcionki do fonts.google.com i kiedy jest ona dostępna na dostępny do pobrania interfejs API czcionek (w systemie wyświetlania lub w narzędziu Compose). Niedawno dodane czcionki mogą nie wczytać się w aplikacji z parametrem IllegalStateException Aby ułatwić programistom zidentyfikowanie tego błędu wśród innych typów błędów wczytywania czcionek, dodaliśmy opis wyjątku w funkcji Utwórz ze zmianami tutaj. Jeśli znajdziesz jakieś problemy, zgłoś je na podstawie problemu .

Używanie czcionek zmiennych

Czcionka zmiennej to format czcionki, który pozwala plikowi czcionki na różne stylów. Dzięki zmiennym czcionkom można modyfikować osie (lub parametry), by generować preferowany styl. Osie te mogą być standardowe, np. waga, szerokość, nachylenie, czy kursywa lub niestandardowe, które różnią się w zależności od czcionki.

Pięć konfiguracji tej samej czcionki zmiennej z różnymi wartościami na osi.
Rysunek 1. Tekst korzystający z tej samej czcionki zmiennej dostosowanej za pomocą różnych osi .

Jeśli zamiast zwykłych plików czcionek użyjesz czcionek zmiennych, możesz mieć tylko jedną pliku czcionki.

Więcej informacji na temat czcionek zmiennych znajdziesz na stronie Google Fonts Wiedza, cały katalog dostępnych zmienne i tabelę obsługiwanych osi dla każdej z nich czcionki.

Ten dokument pokazuje, jak wdrożyć czcionkę zmiennej w aplikacji Compose.

Wczytywanie czcionki zmiennej

  1. Pobierz czcionkę zmiennej, której chcesz użyć (np. Roboto Flex) i umieść go w folderze app/res/font swojej aplikacji. Upewnij się, że plikttf jest zmienną wersją czcionki czcionki, a nazwa plik czcionki jest zapisany małymi literami i nie zawiera żadnych znaków specjalnych.

  2. Aby wczytać czcionkę zmiennej, określ FontFamily za pomocą czcionki umieszczonej w polu Katalog 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),
                )
            )
        )

    Interfejs FontVariation API umożliwia konfigurowanie standardowych osie czcionek, takich jak weight, width i nachylenie. To są standardowe osie, które są z dowolną czcionką o zmiennej. Możesz tworzyć różne konfiguracje w zależności od tego, gdzie czcionka będzie używana.

  3. Czcionki zmiennych są dostępne tylko na Androidzie O lub nowszym, więc dodaj i skonfigurować odpowiednią konfigurację zastępczą:

    // 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
    }

  4. Wyodrębnij ustawienia do zestawu stałych, aby ułatwić ponowne wykorzystanie i zastąpić ustawienia czcionki z tymi stałymi:

    // 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
    }

  5. Skonfiguruj typografię interfejsu Material Design 3, aby korzystać z interfejsu FontFamily:

    // Type.kt
    val Typography = Typography(
        displayLarge = TextStyle(
            fontFamily = displayLargeFontFamily,
            fontSize = 50.sp,
            lineHeight = 64.sp,
            letterSpacing = 0.sp,
            /***/
        )
    )

    W tym przykładzie zastosowano displayLarge typografię Material 3, która różni się domyślnych ustawieniach czcionek i zalecanych zastosowaniach. Na przykład użyj displayLarge w przypadku krótkiego, krytycznego tekstu – jest to największy tekst na ekranie.

    W przypadku Material 3 możesz zmienić wartości domyślne TextStyle i fontFamily, aby dostosować typografię. W powyższym fragmencie kodu skonfigurujesz TextStyle, aby dostosować ustawienia czcionek dla każdej rodziny.

  6. Gdy już zdefiniujesz typografię, przekaż ją do MaterialTheme M3:

    MaterialTheme(
        colorScheme = MaterialTheme.colorScheme,
        typography = Typography,
        content = content
    )

  7. Na koniec użyj funkcji kompozycyjnej Text i określ styl do jednego ze zdefiniowanych style typografii, 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
                    )
                }
            }
        }
    }

    Każdy element kompozycyjny Text jest konfigurowany za pomocą stylu motywu Material ma inną konfigurację czcionki zmiennej. Za pomocą MaterialTheme.typography, aby pobrać typografię udostępnioną mechanizmowi M3 Funkcja MaterialTheme kompozycyjna.

.
Trzy różne teksty o różnych konfiguracjach czcionek.
Rys. 2. Czcionka zmiennej została zastosowana w 3 różnych konfiguracjach.

Użyj niestandardowych osi

Czcionki mogą też mieć niestandardowe osie. Są one zdefiniowane w pliku czcionek. Na przykład czcionka Roboto Flex ma oś wysokości rosnącej ("YTAS"), która dostosowuje wysokość małych liter rosnących, a szerokość licznika ("XTRA") dostosowuje szerokość każdej litery.

Możesz zmienić wartości tych osi w ustawieniach FontVariation.

Więcej informacji o niestandardowych osiach, które można skonfigurować dla czcionki, znajdziesz w tabelę obsługiwanych osi dla każdej czcionki.

  1. Aby używać niestandardowych osi, zdefiniuj funkcje niestandardowych ascenderHeight i Osie (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())
    }

    Te funkcje:

    • Zdefiniowanie barier dla wartości, które mogą akceptować. Jak widać w w katalogu czcionek ze zmiennymi, ascenderHeight (YTAS) zawiera minimalna wartość 649f i maksymalna 854f.
    • Przywróć ustawienie czcionki, aby konfiguracja była gotowa do dodania do czcionki. W w metodzie FontVariation.Setting() nazwa osi (YTAS, XTRA) to jest zakodowany na stałe i przyjmuje wartość jako parametr.
  2. Korzystając z osi z konfiguracją czcionki, przekaż dodatkowe parametry do każdy wczytany element 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
    }

    Zwróć uwagę, że wysokość liter alfabetu łacińskiego została zwiększona, a Inny tekst jest szerszy:

.
Trzy różne teksty z różnymi konfiguracjami czcionek zmiennych i ustawionymi niestandardowymi osiami. Niektóre z nich mają szersze litery z wysokością pisane małymi literami i są szersze niż wcześniej.
Rys. 3. Tekst przedstawiający niestandardowe osie ustawione na zmiennych czcionkach.

Dodatkowe materiały

Więcej informacji znajdziesz w następującym poście na blogu na temat czcionek zmiennych:

. .