How to Implement Custom Fonts using Downloadable Google Fonts?
Tags: android, kotlin, beginners, jetpackcompose
Published: 2023-03-31 23:00:00

**A step-by-step guide to implementing custom font by downloading (instead of manually copying) Google fonts and using them in your Jetpack Compose app.**

**Roboto is the default font** used by Material 3. However, we often want to change it for our app. Instead of manually copying the font asset, you can now download the Google font asynchronously and use them in your Jetpack Compose app.

This is a quick guide to changing the **default Roboto** font to **Arvo** font.

## 1\. Add the dependency

**build.gradle.kts** example

```kotlin
dependencies {
    /*...*/
    implementation("androidx.compose.ui:ui-text-google-fonts:1.3.2")
}
```

## 2\. Copy font\_cert.xml

Copy the [**font-cert.xml**](https://github.com/vinchamp77/YoutubeWorkouts/blob/master/app/src/main/res/values/font_certs.xml) to your **res\\values** folder.

## 3\. Create Font Provider

In **Type.kt**, create the `GoogleFont.Provider`:

```kotlin
@OptIn(ExperimentalTextApi::class)
private val fontProvider = GoogleFont.Provider(
    providerAuthority = "com.google.android.gms.fonts",
    providerPackage = "com.google.android.gms",
    certificates = R.array.com_google_android_gms_fonts_certs
)
```

## 4\. Create Google Font

Search the [Google Font](https://fonts.google.com/) that you would like to use here. In this example, we're going to use **Arvo** font.

> Not all fonts are supported, so you need to try them by yourself. If the font is not supported, it reverts to **Roboto** font.

In **Type.kt**, create the `GoogleFont`:

```kotlin
@OptIn(ExperimentalTextApi::class)
private val googleFont = GoogleFont("Arvo")
```

## 5\. Create Font Family

In **Type.kt**, create the `FontFamily`:

```kotlin
@OptIn(ExperimentalTextApi::class)
private val fontFamily = FontFamily(
    Font(googleFont = googleFont, fontProvider = fontProvider)
)
```

## 6\. Override the Typography

In **Type.kt**, overrides `fontFamily` in the `Typography`:

```kotlin
private val typography = Typography()
val Typography = Typography(
    displayLarge = typography.displayLarge.copy(fontFamily = fontFamily),
    displayMedium = typography.displayMedium.copy(fontFamily = fontFamily),
    displaySmall = typography.displaySmall.copy(fontFamily = fontFamily),

    headlineLarge = typography.headlineLarge.copy(fontFamily = fontFamily),
    headlineMedium = typography.headlineMedium.copy(fontFamily = fontFamily),
    headlineSmall = typography.headlineSmall.copy(fontFamily = fontFamily),

    titleLarge = typography.titleLarge.copy(fontFamily = fontFamily),
    titleMedium = typography.titleMedium.copy(fontFamily = fontFamily),
    titleSmall = typography.titleSmall.copy(fontFamily = fontFamily),

    bodyLarge = typography.bodyLarge.copy(fontFamily = fontFamily),
    bodyMedium = typography.bodyMedium.copy(fontFamily = fontFamily),
    bodySmall = typography.bodySmall.copy(fontFamily = fontFamily),

    labelLarge = typography.labelLarge.copy(fontFamily = fontFamily),
    labelMedium = typography.labelMedium.copy(fontFamily = fontFamily),
    labelSmall = typography.labelSmall.copy(fontFamily = fontFamily),
)
```

## 7\. Use the New Typography

Make sure in your **Theme.kt,** the newly created `Typography` above is passed to the `MaterialTheme()`. Example:

```kotlin
@Composable
fun YourAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    useSystemUIController: Boolean = true,
    content: @Composable () -> Unit
) {
    /*...*/
    MaterialTheme(
        colorScheme = colorScheme,
        shapes = Shapes,
        typography = Typography,
        content = content,
    )
}
```

## Reference

[Downloadable fonts](https://developer.android.com/jetpack/compose/text#downloadable-fonts) (from the official doc)

## Example

GitHub Repository: [YouTubeWorkouts](https://github.com/vinchamp77/YoutubeWorkouts)

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/how-to-implement-custom-fonts-using-downloadable-google-fonts)*.