Mit Schriftarten arbeiten

Auf dieser Seite wird beschrieben, wie Sie Schriftarten in Ihrer Compose-App festlegen.

Schriftart festlegen

Text hat einen fontFamily-Parameter, mit dem Sie die Schriftart festlegen können, die in der zusammensetzbaren Funktion verwendet wird. Standardmäßig sind die Schriftfamilien Serif, Sans-Serif, Monospace und Cursive enthalten:

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

Der Text

Sie können das Attribut fontFamily verwenden, um mit benutzerdefinierten Schriftarten und Schriftbildern zu arbeiten, die im Ordner res/font definiert sind:

Grafische Darstellung des Ordners „res“ > „font“ in der Entwicklungsumgebung

In diesem Beispiel wird gezeigt, wie Sie eine fontFamily basierend auf diesen Schriftart dateien und mit der Font Funktion definieren:

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

Sie können diese fontFamily an Ihre zusammensetzbare Funktion Text übergeben. Da eine fontFamily verschiedene Strichstärken enthalten kann, können Sie fontWeight manuell festlegen, um die richtige Strichstärke für Ihren Text auszuwählen:

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

Der Text

Informationen zum Festlegen der Typografie in Ihrer gesamten App finden Sie unter Benutzerdefinierte Designsysteme in Compose.

Herunterladbare Schriftarten

Ab Compose 1.2.0, können Sie die API für herunterladbare Schriftarten in Ihrer Compose-App verwenden, um Google Schriftarten asynchron herunterzuladen und in Ihrer App zu verwenden.

Die Unterstützung für herunterladbare Schriftarten, die von benutzerdefinierten Anbietern bereitgestellt werden, ist derzeit nicht verfügbar.

Herunterladbare Schriftarten programmatisch verwenden

So laden Sie eine Schriftart programmatisch aus Ihrer App herunter:

  1. Fügen Sie die Abhängigkeit hinzu:

    Groovy

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

    Kotlin

    dependencies {
        ...
        implementation("androidx.compose.ui:ui-text-google-fonts:1.10.5")
    }
  2. Initialisieren Sie GoogleFont.Provider mit den Anmeldedaten für 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
    )
    Die Parameter, die der Anbieter erhält, sind:
    • Die Zertifizierungsstelle des Schriftartenanbieters für Google Fonts.
    • Das Schriftartenanbieterpaket, um die Identität des Anbieters zu bestätigen.
    • Eine Liste mit Hashsätzen für die Zertifikate, um die Identität des Anbieters zu bestätigen. Die für den Google Fonts-Anbieter erforderlichen Hashs finden Sie in der Datei font_certs.xml in der Jetchat-Beispiel-App.
  3. Definieren Sie eine 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)
    )
    Sie können mit FontWeight und FontStyle nach anderen Parametern für Ihre Schriftart wie Strichstärke und Stil suchen:
    // ...
     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. Konfigurieren Sie die FontFamily für die Verwendung in Ihrer zusammensetzbaren Funktion „Text“:

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

Sie können auch die Typografie definieren, um Ihre FontFamily zu verwenden:

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

Legen Sie als Nächstes die Typografie für das Design Ihrer App fest:

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

Ein Beispiel für eine App, in der herunterladbare Schriftarten in Compose zusammen mit Material 3implementiert werden, finden Sie in der Jetchat-Beispiel-App.

Fallback-Schriftarten hinzufügen

Sie können eine Kette von Fallbacks für Ihre Schriftart festlegen, falls die Schriftart nicht ordnungsgemäß heruntergeladen werden kann. Wenn Sie beispielsweise Ihre herunterladbare Schriftart so definiert haben:

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

Sie können die Standardwerte für Ihre Schriftart für beide Strichstärken so definieren:

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

Achten Sie darauf, dass Sie die richtigen Importe hinzufügen.

Wenn Sie die FontFamily so definieren, wird eine FontFamily mit zwei Ketten erstellt, eine pro Strichstärke. Der Lademechanismus versucht zuerst, die Online-Schriftart aufzulösen, und dann die Schriftart im lokalen R.font-Ressourcenordner.

Fehler in der Implementierung beheben

Damit Sie prüfen können, ob die Schriftart korrekt heruntergeladen wird, können Sie einen Debug-Coroutine-Handler definieren. Ihr Handler gibt das Verhalten an, das ausgeführt werden soll, wenn die Schriftart nicht asynchron geladen werden kann.

Erstellen Sie zuerst einen CoroutineExceptionHandler:

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

Übergeben Sie ihn an die createFontFamilyResolver Methode, damit der Resolver den neuen Handler verwendet:

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

Sie können auch die isAvailableOnDevice -API des Anbieters verwenden, um zu testen, ob der Anbieter verfügbar ist und die Zertifikate richtig konfiguriert sind. Rufen Sie dazu die Methode isAvailableOnDevice auf, die „false“ zurückgibt, wenn der Anbieter falsch konfiguriert ist.

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

Vorsichtsmaßnahmen

Es dauert mehrere Monate, bis Google Fonts neue Schriftarten auf Android verfügbar macht. Es gibt eine Zeitverzögerung zwischen dem Hinzufügen einer Schriftart in fonts.google.com und ihrer Verfügbarkeit über die API für herunterladbare Schriftarten (entweder im View-System oder in Compose). Neu hinzugefügte Schriftarten können in Ihrer App mit einer IllegalStateException nicht geladen werden. Damit Entwickler diesen Fehler von anderen Arten von Fehlern beim Laden von Schriftarten unterscheiden können, haben wir mit den Änderungen hier beschreibende Meldungen für die Ausnahme in Compose hinzugefügt. Wenn Sie Probleme feststellen, melden Sie sie über die Problem verfolgung.

Variable Schriftarten verwenden

Eine variable Schriftart ist ein Schriftartformat, das es ermöglicht, dass eine Schriftartdatei verschiedene Stile enthält. Mit variablen Schriftarten können Sie Achsen (oder Parameter) ändern, um den gewünschten Stil zu generieren. Diese Achsen können Standardachsen wie Strichstärke, Breite, Neigung und Kursiv oder benutzerdefiniert sein, die sich je nach variabler Schriftart unterscheiden.

Fünf Konfigurationen derselben variablen Schriftart mit unterschiedlichen Achsenwerten.
Abbildung 1. Text mit derselben variablen Schriftart, die mit verschiedenen Achsenwerten angepasst wurde.

Wenn Sie variable Schriftarten anstelle von regulären Schriftartdateien verwenden, benötigen Sie nur eine Schriftartdatei anstelle von mehreren.

Weitere Informationen zu variablen Schriftarten finden Sie unter Google Fonts Knowledge, im gesamten Katalog der verfügbaren variablen Schriftarten und in einer Tabelle der unterstützten Achsen für jede Schriftart.

In diesem Dokument wird beschrieben, wie Sie eine variable Schriftart in Ihrer Compose-App implementieren.

Variable Schriftart laden

  1. Laden Sie die gewünschte variable Schriftart herunter (z. B. Roboto Flex) und platzieren Sie sie in Ihrer App im Ordner app/res/font. Achten Sie darauf, dass die .ttf -Datei, die Sie hinzufügen, die variable Schriftartversion der Schriftart ist und dass der Name Ihrer Schriftartdatei nur Kleinbuchstaben enthält und keine Sonderzeichen.

  2. Um eine variable Schriftart zu laden, definieren Sie eine FontFamily mit der Schriftart im Verzeichnis 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),
                )
            )
        )

    Mit der FontVariation-API können Sie Standardachsen für Schriftarten wie Strichstärke, Breite und Neigung konfigurieren. Das sind Standardachsen, die mit jeder variablen Schriftart verfügbar sind. Sie können verschiedene Konfigurationen der Schriftart erstellen, je nachdem, wo sie verwendet wird.

  3. Variable Schriftarten sind nur für Android-Versionen O und höher verfügbar. Fügen Sie daher eine Schutzvorrichtung hinzu und konfigurieren Sie ein entsprechendes Fallback:

    // 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. Extrahieren Sie die Einstellungen in eine Reihe von Konstanten, um sie einfacher wiederzuverwenden, und ersetzen Sie die Schriftarteinstellungen durch diese Konstanten:

    // 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. Konfigurieren Sie die Material Design 3-Typografie für die Verwendung der FontFamily:

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

    In diesem Beispiel wird die displayLarge Material 3-Typografie verwendet, die andere Standardschriftarteinstellungen und empfohlene Verwendungszwecke hat. Verwenden Sie displayLarge beispielsweise für kurzen, wichtigen Text, da es sich um den größten Text auf dem Bildschirm handelt.

    Mit Material 3 können Sie die Standardwerte von TextStyle und fontFamily ändern, um die Typografie anzupassen. Im obigen Snippet konfigurieren Sie Instanzen von TextStyle, um die Schriftarteinstellungen für jede Schriftfamilie anzupassen.

  6. Nachdem Sie die Typografie definiert haben, übergeben Sie sie an das M3-MaterialTheme:

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

  7. Verwenden Sie schließlich eine zusammensetzbare Funktion Text und legen Sie den Stil auf einen der definierten Typografiestile fest, z. B. 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
                    )
                }
            }
        }
    }

    Jede zusammensetzbare Funktion Text wird über den Stil des Material-Designs konfiguriert und enthält eine andere Konfiguration für variable Schriftarten. Mit MaterialTheme.typography können Sie die Typografie abrufen, die der zusammensetzbaren Funktion von M3 MaterialTheme bereitgestellt wird.

Drei verschiedene Texte, die jeweils unterschiedliche Schriftkonfigurationen zeigen.
Abbildung 2. Variable Schriftart in drei verschiedenen Konfigurationen angewendet.

Benutzerdefinierte Achsen verwenden

Schriftarten können auch benutzerdefinierte Achsen haben. Diese werden in der Schriftartdatei selbst definiert. Die Schriftart Roboto Flex hat beispielsweise die Achse für die Höhe der Oberlänge ("YTAS"), mit der die Höhe der Kleinbuchstaben-Oberlängen angepasst wird, während die Breite des Gegenraums ("XTRA") die Breite jedes Buchstabens anpasst.

Sie können den Wert dieser Achsen mit den FontVariation-Einstellungen ändern.

Weitere Informationen zu den benutzerdefinierten Achsen, die Sie für eine Schriftart konfigurieren können, finden Sie in der Tabelle der unterstützten Achsen für jede Schriftart.

  1. Um benutzerdefinierte Achsen zu verwenden, definieren Sie Funktionen für die benutzerdefinierten Achsen ascenderHeight und 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())
    }

    Diese Funktionen führen Folgendes aus:

    • Sie definieren Schutzvorrichtungen für die Werte, die sie akzeptieren können. Wie Sie im Katalog für variable Schriftarten sehen, hatascenderHeight (YTAS) einen Mindestwert von 649f und einen Höchstwert von 854f.
    • Sie geben die Schriftarteinstellung zurück, damit die Konfiguration der Schriftart hinzugefügt werden kann. In der Methode FontVariation.Setting() ist der Achsenname (YTAS, XTRA) fest codiert und der Wert wird als Parameter verwendet.
  2. Wenn Sie die Achsen mit der Schriftartkonfiguration verwenden, übergeben Sie zusätzliche Parameter an jede geladene 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
    }

    Die Höhe der Kleinbuchstaben-Oberlängen ist jetzt größer und der andere Text ist breiter:

Drei verschiedene Texte mit unterschiedlichen Konfigurationen für variable Schriftarten mit benutzerdefinierten Achsen – einige haben höhere Kleinbuchstaben-Oberlängen und sind breiter als zuvor.
Abbildung 3. Text mit benutzerdefinierten Achsen, die für variable Schriftarten festgelegt wurden.

Zusätzliche Ressourcen

Weitere Informationen finden Sie im folgenden Blogpost zu variablen Schriftarten: