Mit Schriftarten arbeiten

Auf dieser Seite wird beschrieben, wie Sie Schriftarten in der App „Schreiben“ festlegen.

Schriftart festlegen

Text hat einen fontFamily-Parameter, mit dem die in der zusammensetzbaren Funktion verwendete Schriftart festgelegt werden kann. Standardmäßig sind die Schriftarten mit Serifen-, Sans-Serif-, Festbreiten- und kursiven Schriftarten eingeschlossen:

@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 Schriftarten zu arbeiten, die im Ordner res/font definiert sind:

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

Das folgende Beispiel zeigt, wie Sie eine fontFamily anhand dieser Schriftartdateien und mit 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 eine fontFamily unterschiedliche Schriftstärken enthalten kann, können Sie fontWeight manuell so festlegen, dass die richtige Schriftstärke für Ihren Text ausgewählt wird:

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

Gehen Sie folgendermaßen vor, um eine Schriftart programmatisch aus Ihrer App herunterzuladen:

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

    Cool

    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. 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
    )
    Der Anbieter erhält folgende Parameter:
    • Die Befugnis des Schriftartenanbieters für Google Fonts.
    • Das Paket des Schriftartanbieters, um die Identität des Anbieters zu überprüfen
    • Eine Liste von Hash-Sätzen für die Zertifikate, mit denen die Identität des Anbieters überprüft werden kann. Die für den Google Fonts-Anbieter erforderlichen Hashes finden Sie in der Jetchat-Beispielanwendung in der Datei font_certs.xml.
  3. Definiere 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)
    )
    Du kannst mit FontWeight und FontStyle andere Parameter für deine 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, die in der zusammensetzbaren Textfunktion verwendet werden soll:

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

Sie können auch eine Typografie definieren, um Ihren FontFamily zu verwenden:

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

Wählen Sie als Nächstes für die Typografie das Design Ihrer App aus:

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 Kette von Fallbacks für Ihre Schriftart ermitteln, 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)
)

Sie können die Standardeinstellungen für die Schriftart für beide Schriftstärken wie folgt festlegen:

// ...
 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, die richtigen Importe hinzuzufügen.

Wenn Sie das FontFamily so definieren, wird ein FontFamily erstellt, der zwei Ketten enthält, eine pro Gewichtung. Der Lademechanismus versucht zuerst, die Online-Schriftart und dann die Schriftart im lokalen R.font-Ressourcenordner aufzulösen.

Fehler in der Implementierung beheben

Damit Sie prüfen können, ob die Schriftart korrekt heruntergeladen wird, können Sie einen Handler für die Fehlerbehebung definieren. Über den Handle wird festgelegt, was zu tun ist, wenn die Schriftart nicht asynchron 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 Zertifikate korrekt 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 von Google Fonts für Android verfügbar sind. Nachdem eine Schriftart auf fonts.google.com hinzugefügt wurde, gibt es eine zeitliche Verzögerung, bis sie über die herunterladbare Fonts API (entweder im View-System oder in Compose) verfügbar ist. Neu hinzugefügte Schriftarten werden in Ihrer Anwendung möglicherweise nicht mit einem IllegalStateException geladen. 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. Wenn Sie Probleme finden, melden Sie sie über die Problemverfolgung.

Variable Schriftarten verwenden

Eine variable Schriftart ist ein Schriftformat, in dem eine Schriftartdatei verschiedene Stile enthalten kann. Bei variablen Schriftarten können Sie Achsen (oder Parameter) ändern, um den gewünschten Stil zu generieren. Dabei kann es sich um Standardachsen wie „Gewichtung“, „Breite“, „Schrägstrich“ und „Kursiv“ oder „Benutzerdefiniert“ handeln, die sich je nach variablen Schriftarten unterscheiden.

Fünf Konfigurationen derselben Variablenschrift mit unterschiedlichen Achsenwerten.
Abbildung 1. Text mit derselben Variablenschrift, die mit unterschiedlichen Achsenwerten angepasst wird.

Wenn Sie variable Schriftarten anstelle von regulären Schriftarten verwenden, können Sie statt mehrerer nur eine Schriftartdatei verwenden.

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

In diesem Dokument erfahren Sie, wie Sie eine variable Schriftart in der Compose-App implementieren.

Variable Schriftart laden

  1. Laden Sie die zu verwendende Schriftart für die Variable herunter (z. B. Roboto Flex) und speichern Sie sie im Ordner app/res/font Ihrer Anwendung. Achten Sie darauf, dass die .ttf ist die variable Schriftartversion der Schriftart, und der Name der Schriftartdatei ist nur in Kleinbuchstaben geschrieben und enthält keine Sonderzeichen.

  2. Wenn Sie eine variable Schriftart laden möchten, 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 Standardschriftachsen wie Gewichtung, Breite und Schrägung konfigurieren. Dies sind Standardachsen, die in beliebiger Schriftart verfügbar sind. Je nachdem, wo Sie die Schriftart verwenden, können Sie verschiedene Konfigurationen erstellen.

  3. Variable Schriftarten sind nur für Android-Version O und höher verfügbar. Fügen Sie deshalb eine Schutzmaßnahmen hinzu und konfigurieren Sie ein geeignetes 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 zur einfacheren Wiederverwendung in einen Satz von Konstanten 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. Konfiguriere die Typografie von Material Design 3 für die Verwendung von FontFamily:

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

    In diesem Beispiel wird displayLarge Material 3-Typografie verwendet, die andere Standardschrifteinstellungen hat und die Verwendung empfohlen wird. Sie sollten beispielsweise displayLarge für kurzen, wichtigen Text verwenden, da dies der größte Text auf dem Bildschirm ist.

    Bei Material 3 kannst du die Standardwerte von TextStyle und fontFamily ändern, um deine 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 schließlich eine zusammensetzbare Funktion Text 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
                    )
                }
            }
        }
    }

    Jede zusammensetzbare Text-Funktion wird anhand des Stils ihres Material-Designs konfiguriert und enthält eine andere variable Schriftart. Mit MaterialTheme.typography können Sie die Typografie abrufen, die der M3-Zusammensetzbaren MaterialTheme-Funktion zur Verfügung gestellt wird.

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

Benutzerdefinierte Achsen verwenden

Schriftarten können auch benutzerdefinierte Achsen haben. Diese werden in der Schriftartdatei selbst definiert. In der Schriftart Roboto Flex wird beispielsweise die Höhe der Aufstiegshöhe ("YTAS") der Schriftart von Roboto Flex angepasst, durch die die Höhe der Oberlängen in Kleinbuchstaben angepasst wird, während die Zählerbreite ("XTRA") die Breite der einzelnen Buchstaben anpasst.

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 die jeweilige 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 führen Folgendes aus:

    • Definieren Sie Schutzmaßnahmen für die Werte, die akzeptiert werden. Wie Sie im Katalog mit Variablen für Schriftarten sehen können, 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 verwendet den Wert als Parameter.
  2. Übergeben Sie unter Verwendung der Achsen mit der Schriftartkonfiguration jedem geladenen Font zusätzliche Parameter:

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

    Beachten Sie, dass die Höhe der Oberlängen in Kleinbuchstaben jetzt und der andere Text breiter ist:

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

Zusätzliche Ressourcen

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