visible true

技術的なメモを書く

Jetpack Composeでカスタムフォントを使う

Jetpack Composeでカスタムフォントを使うには、FontFamily を用いる。

res/fontにフォントファイルを置き、FontFamilyにFontを渡す。

// res/font/ipam.ttfがあるとすると次のようになる。
FontFamily(
  Font(name = "ipam.ttf", weight = FontWeight.W400, style = FontStyle.Normal)
)

使う

実際使う際は次のように+memoなんかを使って取り出しておき、TextStyleにセットする。

@Preview
@Composable
fun CustomFontSample() {
    val fontFamily = +memo {
        FontFamily(
            Font(name = "ipam.ttf", weight = FontWeight.W400, style = FontStyle.Normal)
        )
    }
    Text(
        text = "こんにちは",
        style = TextStyle(
            fontSize = 14.sp,
            fontFamily = fontFamily
        )
    )
}

こうなる。

f:id:sys1yagi:20200118024058p:plain

ambientを用意する

使う箇所で毎度取り出すのは煩雑なのでambientを用意しておくとよさそう。

import androidx.compose.Ambient
import androidx.compose.Composable
import androidx.compose.memo
import androidx.compose.unaryPlus
import androidx.ui.text.font.Font
import androidx.ui.text.font.FontFamily
import androidx.ui.text.font.FontStyle
import androidx.ui.text.font.FontWeight

val IpamFontAmbient = Ambient.of<FontFamily>()

@Composable
fun IpamFontProvider(children : @Composable() () -> Unit) {
    val fontFamily = +memo {
        FontFamily(
            Font(name = "ipam.ttf", weight = FontWeight.W400, style = FontStyle.Normal)
        )
    }
    IpamFontAmbient.Provider(value = fontFamily, children = children)
}

次のようにIpamFontProviderのchildで+ambient関数を使ってProvideしているFontFamilyを取り出せるようになる。

@Preview
@Composable
fun CustomFontSample() {
    IpamFontProvider {
        val fontFamily = +ambient(IpamFontAmbient)
        Text(
            text = "こんにちは",
            style = TextStyle(
                fontSize = 14.sp,
                fontFamily = fontFamily
            )
        )
    }
}

setContent辺りの根本で囲んでおけばアプリ全体でどこでも取り出せるようになる。 このあたりはFlutterのproviderに考え方が似てるんじゃないかと思う。

おわりに

Compose面白い。