Mit Schriftarten arbeiten

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

Schriftart festlegen

Text hat einen fontFamily-Parameter, mit dem die in der zusammensetzbaren Funktion verwendete Schriftart festgelegt werden kann. Standardmäßig sind Schriftfamilien mit Serifen, ohne Serifen, monospace und kursiv enthalten:

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

Der Text

Mit dem fontFamily-Attribut können Sie mit benutzerdefinierten Schriftarten und Schriftschnitten 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 anhand dieser Schriftdateien und mithilfe der Funktion Font 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 diesen fontFamily an Ihre zusammensetzbare Funktion Text übergeben. Da ein fontFamily verschiedene Gewichte enthalten kann, können Sie fontWeight manuell festlegen, um das richtige Gewicht 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-Version 1.2.0 können Sie die herunterladbare Fonts API in der Compose-App verwenden, um Google Fonts asynchron herunterzuladen und in Ihrer Anwendung zu verwenden.

Derzeit werden keine Schriftarten unterstützt, die von benutzerdefinierten Anbietern heruntergeladen werden können.

Herunterladbare Schriftarten programmatisch verwenden

So laden Sie einen Schriftschnitt programmatisch über Ihre App herunter:

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

    Groovy

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

    Kotlin

    dependencies {
        ...
        implementation("androidx.compose.ui:ui-text-google-fonts:1.7.5")
    }
  2. Initialisieren Sie die 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
    )
    Der Anbieter erhält folgende Parameter:
    • Die Schriftanbieter-Autorität für Google Fonts.
    • Das Paket des Schriftartenanbieters zur Bestätigung der Identität des Anbieters.
    • Eine Liste von Hash-Sätzen für die Zertifikate zur Überprüfung der Identität des Anbieters. Die für den Google Fonts-Anbieter erforderlichen Hash-Werte finden Sie in der Datei font_certs.xml in der Beispiel-App „Jetchat“.
  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 bzw. FontStyle andere Parameter für Ihre Schriftart wie Stärke und Stil abfragen:
    // ...
     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 Textfunktion:

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

Sie können auch Typografie für die Verwendung Ihres FontFamily definieren:

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 Schriftarten zum Herunterladen in Compose zusammen mit Material3 implementiert werden, finden Sie in der Beispiel-App Jetchat.

Fallback-Schriftarten hinzufügen

Sie können eine Abfolge von Fallbacks für Ihre Schriftart festlegen, falls die Schriftart nicht richtig heruntergeladen werden kann. Angenommen, Sie haben Ihre herunterladbare Schriftart so definiert:

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

So können Sie die Standardeinstellungen für Ihre Schriftart für beide Stärken 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 das FontFamily so definieren, wird ein FontFamily erstellt, der zwei Ketten enthält, eine pro Gewichtung. Der Ladevorgang versucht zuerst, die Onlineschriftart und dann die Schriftart im lokalen R.font-Ressourcenordner zu finden.

Implementierung debuggen

Sie können einen Debug-Coroutinen-Handler definieren, um zu prüfen, ob die Schrift richtig heruntergeladen wird. Der Handle gibt an, was passieren soll, wenn die Schrift asynchron nicht geladen werden kann.

Erstellen Sie zuerst eine CoroutineExceptionHandler:

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

Übergeben Sie ihn an die Methode createFontFamilyResolver, 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. Dazu können Sie die Methode isAvailableOnDevice aufrufen, die „false“ zurückgibt, wenn der Anbieter falsch konfiguriert ist.

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

Einschränkungen

Es dauert mehrere Monate, bis neue Schriftarten bei Google Fonts für Android verfügbar sind. Zwischen dem Hinzufügen einer Schriftart unter fonts.google.com und der Verfügbarkeit über die Downloadable Fonts API (entweder im Ansichtssystem oder in Compose) vergeht eine gewisse Zeit. Neu hinzugefügte Schriftarten werden in Ihrer App möglicherweise nicht geladen und durch ein IllegalStateException ersetzt. Damit Entwickler diesen Fehler gegenüber anderen Arten von Fehlern beim Laden von Schriftarten besser erkennen können, haben wir in „Compose“ eine beschreibende Mitteilung für die Ausnahme mit den Änderungen hier hinzugefügt. Falls Probleme auftreten, melden Sie sie über den Issue Tracker.

Variable Schriftarten verwenden

Ein variabler Schriftschnitt ist ein Schriftformat, bei dem eine Schriftdatei verschiedene Stile enthalten kann. Mit variablen Schriftarten können Sie Achsen (oder Parameter) ändern, um Ihren bevorzugten Stil zu generieren. Diese Achsen können standardmäßig sein, z. B. „Schriftstärke“, „Breite“, „Schrägstellung“ und „Kursiv“, oder benutzerdefiniert, was sich je nach variabler Schriftart unterscheidet.

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 regulärer Schriftartendateien verwenden, benötigen Sie nur eine Schriftartendatei anstelle mehrerer.

Weitere Informationen zu variablen Schriftarten finden Sie unter Google Fonts-Wissen, im vollständigen Katalog der verfügbaren variablen Schriftarten und in einer Tabelle mit den unterstützten Achsen für jede Schriftart.

In diesem Dokument erfahren Sie, 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 legen Sie sie in den Ordner app/res/font in Ihrer App ab.ttf-Datei, die Sie hinzufügen, die variable Schriftversion der Schrift ist und der Name der Schriftdatei nur Kleinbuchstaben enthält und keine Sonderzeichen.

  2. Wenn Sie eine variable Schriftart laden möchten, definieren Sie eine FontFamily mit der Schriftart, die sich im Verzeichnis res/font/ befindet:

    // 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 Standard-Schriftachsen wie weight (Stiftstärke), width (Breite) und slant (Schrägstellung) konfigurieren. Dies sind Standardachsen, die mit jeder variablen Schrift verfügbar sind. Je nachdem, wo der Schriftschnitt verwendet wird, können Sie verschiedene Konfigurationen erstellen.

  3. Variable Schriftarten sind nur für Android-Versionen ab O verfügbar. Fügen Sie daher eine Sicherheitsmaßnahme hinzu und konfigurieren Sie einen geeigneten 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 leichter wiederverwenden zu können, und ersetzen Sie die Schrifteinstellungen 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 Typografie von Material Design 3 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 Standardschrifteinstellungen und empfohlene Verwendungen hat. Verwenden Sie displayLarge beispielsweise für kurzen, wichtigen Text, da dies die größte Schriftart auf dem Bildschirm ist.

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

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

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

  7. Verwenden Sie abschließend ein Text-Element und geben Sie als Stil einen der definierten Typografiestile an, 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
                    )
                }
            }
        }
    }

    Jedes Text-Komposit ist über den Stil des Material-Design-Themas konfiguriert und enthält eine andere Variable-Schrift-Konfiguration. Mit MaterialTheme.typography können Sie die Typografie abrufen, die für das M3-MaterialTheme-Komposit bereitgestellt wurde.

Drei verschiedene Texte mit unterschiedlichen Schriftkonfigurationen
Abbildung 2: Variable Schriftart in drei verschiedenen Konfigurationen angewendet.

Benutzerdefinierte Achsen verwenden

Schriftarten können auch benutzerdefinierte Achsen haben. Sie werden in der Schriftdatei selbst definiert. Die Schriftart „Roboto Flex“ hat beispielsweise die Achse „Aufstrichhöhe“ ("YTAS"), mit der die Höhe der Aufstriche von Kleinbuchstaben angepasst wird, während die Achse „Schriftbreite“ ("XTRA") die Breite der einzelnen Buchstaben bestimmt.

Sie können den Wert dieser Achsen mit den Einstellungen für FontVariation ä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. Wenn Sie benutzerdefinierte Achsen verwenden möchten, 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 haben folgende Auswirkungen:

    • Legen Sie Grenzwerte für zulässige Werte fest. Wie Sie im Katalog der variablen Schriftarten sehen, hat ascenderHeight (YTAS) einen Mindestwert von 649f und einen Höchstwert von 854f.
    • Geben Sie die Schriftarteinstellung zurück, damit die Konfiguration zur Schriftart hinzugefügt werden kann. Bei der Methode FontVariation.Setting() ist der Achsenname (YTAS, XTRA) hartcodiert und der Wert wird als Parameter übergeben.
  2. Über die Achsen mit der Schriftkonfiguration können Sie jedem geladenen Font zusätzliche Parameter übergeben:

    @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 Oberlängen der Kleinbuchstaben 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 Aufstrichhöhen bei Kleinbuchstaben und sind breiter als zuvor.
Abbildung 3 Text mit benutzerdefinierten Achsen, die auf variablen Schriftarten basieren.

Weitere Informationen

Weitere Informationen finden Sie im folgenden Blogpost über variable Schriftarten: