フォントを操作する

このページでは、Compose アプリでフォントを設定する方法について説明します。

フォントを設定

Text には、コンポーザブルで使用されるフォントを設定するための fontFamily パラメータを指定できます。デフォルトでは、Serif、Sans Serif、Monospace、Cursive のフォント ファミリーが含まれています

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

キーワード

fontFamily 属性を使用すると、カスタム フォントと書体を使用できます res/font フォルダに定義されています。

開発環境の res > font フォルダの図

この例では、これらのフォントに基づいて fontFamily を定義する方法を示します。 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)
)

この fontFamilyText コンポーザブルに渡すことができます。fontFamily には、異なる太さを含めることが可能です。その場合は、次のように手動で fontWeight を設定して、テキストに適した太さを選択します。

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

キーワード

アプリ全体でタイポグラフィを設定する方法については、Compose のカスタム デザイン システムをご覧ください。

ダウンロード可能なフォント

Compose で開始する 1.2.0、 Compose アプリでダウンロード可能なフォントの API を使用して、Google 非同期に作成して、アプリで使用することもできます。

現在、カスタム プロバイダが提供するダウンロード可能フォントはサポートされていません。

プログラムでダウンロード可能なフォントを使用する

アプリ内からプログラムでフォントをダウンロードする手順は次のとおりです。

  1. 依存関係を追加します。

    Groovy

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

    Kotlin

    dependencies {
        ...
        implementation("androidx.compose.ui:ui-text-google-fonts:1.7.0")
    }
  2. 初期化 GoogleFont.Provider 次のコマンドで説明します。
    val provider = GoogleFont.Provider(
        providerAuthority = "com.google.android.gms.fonts",
        providerPackage = "com.google.android.gms",
        certificates = R.array.com_google_android_gms_fonts_certs
    )
    プロバイダが受け取るパラメータは次のとおりです。
    • Google Fonts のフォント プロバイダの権限
    • プロバイダの ID を確認するためのフォント プロバイダ パッケージ
    • プロバイダの ID を確認するための、証明書のハッシュセットのリストGoogle Fonts プロバイダに必要なハッシュは、Jetchat サンプルアプリの font_certs.xml ファイルで確認できます。
  3. 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)
    )
    太さやスタイルなど、フォントの他のパラメータをクエリするには、 FontWeightFontStyle それぞれ:
    // ...
     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. FontFamily を次のように構成します。 使用する方法を見てみましょう。

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

FontFamily を使用するタイポグラフィを定義することもできます。

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

次に、タイポグラフィをアプリのテーマに設定します。

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

Compose でダウンロード可能なフォントを実装するアプリの例 マテリアル 3 のほか、 Jetchat サンプルアプリをご覧ください。

代替フォントを追加する

フォントがうまく機能しない場合に備えて、フォントの代替の連鎖を決定できます。 適切にダウンロードされます。たとえば、ダウンロード可能フォントが定義済みで、 例:

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

両方のウェイトのデフォルト フォントを次のように定義できます。

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

正しいインポートを追加していることを確認してください。

このように FontFamily を定義すると、2 つのチェーン(ウェイトごとに 1 つ)を含む FontFamily が作成されます。読み込みメカニズムでは、まずオンライン フォントを解決し、次にローカルの R.font リソース フォルダにあるフォントを解決しようとします。

実装をデバッグする

フォントが正しくダウンロードされていることを確認するには、デバッグ コルーチン ハンドラを定義します。ハンドルを使用すると、フォントが非同期でロードされなかった場合に実行する動作を指定できます。

まずは CoroutineExceptionHandler:

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

それを createFontFamilyResolver メソッドを使用して、リゾルバが新しいハンドラを使用するようにします。

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

プロバイダの isAvailableOnDevice API を使用して、プロバイダが利用可能であり、証明書が正しく構成されているかどうかをテストすることもできます。そのためには、isAvailableOnDevice メソッドを呼び出します。 プロバイダが正しく構成されていない場合は false を返します。

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

注意点

Google Fonts では、Android で新しいフォントを利用できるようになるまでに数か月かかります。フォントを追加するタイミングには時間差があります。 fonts.google.com を通じて ダウンロード可能なフォントの API(View システムまたは Compose で)新規 追加されたフォントが、特定の Google ブラウザや IllegalStateException。 デベロッパーがこのエラーと他の種類のフォント読み込みエラーを見分けることができるよう、Compose に例外についての説明メッセージを追加しました。変更内容については、こちらをご覧ください。問題が見つかった場合は、問題番号を使用して報告します 。

可変フォントを使用する

可変フォントは、1 つのフォントファイルにさまざまなスタイルを含めることができるフォント形式です。可変フォントを使用すると、軸(またはパラメータ)を変更して お好みのスタイルに変更できます。これらの軸には、重量、幅、傾斜、 カスタム フォントを使用できます。

同じ変数フォントで軸の値が異なる 5 つの構成。
図 1. 同じ変数フォントを使用し、異なる軸でカスタマイズしたテキスト

通常のフォント ファイルの代わりに可変フォントを使用すると、1 つのフォントのみを使用できます。 フォント ファイルを作成します。

可変フォントの背景について詳しくは、Google Fonts Knowledge、Google Cloud で利用できるカタログ全体 可変フォント、各フォントでサポートされている軸の あります。

このドキュメントでは、Compose アプリに可変フォントを実装する方法について説明します。

可変フォントを読み込む

  1. 使用する可変フォント(Roboto Flex など)をダウンロードします。 アプリの app/res/font フォルダに配置します。.追加する ttf ファイルがフォントの可変フォント バージョンであり、フォント ファイルの名前がすべて小文字で、特殊文字が含まれていないこと。

  2. 可変フォントを読み込むには、FontFamily 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),
                )
            )
        )

    FontVariation API を使用すると、次のような標準フォント軸を設定できます。 重量傾斜。これらは、どの可変フォントでも使用できる標準の軸です。アプリケーションに対してさまざまな構成を作成でき、 使用するフォントのサイズを指定します。

  3. 可変フォントは Android バージョン O 以降でのみ使用できるため、 適切なフォールバックを構成します。

    // 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. 設定を定数に抽出して再利用しやすくし、 次の定数を使用してフォント設定を作成します。

    // 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. FontFamily を使用するようにマテリアル デザイン 3 のタイポグラフィを構成します。

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

    このサンプルでは、displayLarge マテリアル 3 タイポグラフィを使用しています。このタイポグラフィには、デフォルトのフォント設定と推奨される用途が異なります。たとえば、displayLarge は画面上で最も大きいテキストであるため、短く重要なテキストに使用する必要があります。

    マテリアル 3 では、TextStylefontFamily: タイポグラフィをカスタマイズします。上記のスニペットでは、サービス アカウントを TextStyle のインスタンスを使用して、各フォント ファミリーのフォント設定をカスタマイズします。

  6. タイポグラフィを定義したので、それを M3 MaterialTheme に渡します。

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

  7. 最後に、Text コンポーザブルを使用して、スタイルを定義済みの タイポグラフィ スタイル、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 Androids 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
                    )
                }
            }
        }
    }

    Text コンポーザブルは、マテリアル テーマのスタイルと 異なる可変フォント設定が含まれています。次を使用: MaterialTheme.typography: M3 に提供されたタイポグラフィを取得します。 MaterialTheme コンポーザブル。

異なるフォント構成を示す 3 つの異なるテキスト。
図 2. 3 つの異なる構成で適用された可変フォント。

カスタム軸を使用する

フォントにはカスタム軸を設定することもできます。これらはフォント ファイル自体で定義されます。たとえば、Roboto Flex フォントには、小文字のアクセント記号の高さを調整するアクセント記号の高さ("YTAS")軸と、各文字の幅を調整するカウンタ幅("XTRA")軸があります。

これらの軸の値は FontVariation 設定で変更できます。

フォントに設定できるカスタム軸について詳しくは、 各フォントのサポートされている軸の表をご覧ください。

  1. カスタム軸を使用するには、カスタム ascenderHeight の関数を定義します。 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())
    }

    これらの関数は次の処理を行います。

    • 受け入れ可能な値のガードレールを定義します。ご覧のとおり、 可変フォント カタログ: ascenderHeight (YTAS) には 最小値は 649f、最大値は 854f です。
    • フォントの設定を返して、フォントに追加する準備を整えます。イン FontVariation.Setting() メソッドの場合、軸名(YTAS, XTRA)は 値をパラメータとして受け取ります。
  2. フォント設定で軸を使用して、追加のパラメータを 読み込まれる各 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
    }

    小文字のアクセント記号の高さが上がり、他のテキストの幅が広がっています。

で確認できます。 <ph type="x-smartling-placeholder">
</ph> カスタム軸を設定して、可変フォントの構成が異なる 3 つのテキスト。一部のテキストは小文字のアセンダーが高く、以前よりも幅が広くなっています。
図 3.可変フォントで設定されたカスタム軸を示すテキスト。

参考情報

詳細については、可変フォントに関する次のブログ投稿をご覧ください。