Android 開発をしていると、端末のフォントサイズ設定を大きくしたらテキストが大きくなって UI がめちゃめちゃ崩れた…、みたいなことがあるかと思います。
XML レイアウトでは、TextView
の textSize
をあえて dp
指定することで端末のフォントサイズ設定を無視する方法がありました。
Jetpack Compose の場合はどうなのかと調べてみると、意外と簡単に無視できることがわかったので、備忘録として投稿します。
フォントサイズ設定はアクセシビリティにも関与するものなので、むやみに無視するのも好ましくないと考えます。
CompositionLocalProvider
で LocalDensity
を上書きし、fontScale
を調整
LocalDensity.current.fontScale
で現在のフォントサイズ設定が取得できます。
端末のフォントサイズのデフォルトは 1
で、設定を変更するとこの値が 1.15, 1.3, 1.5,...
と変化することが確認できました。
CompositionLocalProvider
を使い、LocalDensity
を任意の Density
で上書きすることで fontScale
を調整することが可能です。
以下は fontScale
を 1 に固定する例です。
CompositionLocalProvider(
LocalDensity provides Density(
LocalDensity.current.density, // そのまま
1F, // fontScaleを1に固定
),
) {
// この中のComposableはfontScaleが1で表示される
}
アプリ全体でフォントサイズ設定を無視したい場合は、アプリのルートでこの指定を書いておけば良さそうです。(注意点)
比較動画
fontScale
をそのままにした場合と 1 に固定した場合で比較してみるとこのようになりました。
fontScale
を 1 に固定した方では、フォントサイズを変更しているのに、テキストのサイズが変更されていないことが確認できます。(ステータスバーの文字は通常通り大きくなっています。)
fontScale:そのまま | fontScale:1 に固定 |
---|---|
![]() |
![]() |
注意点
観測した限り、Dialog
コンポーザブルを使った場合、 Dialog
の content
部分に関しては fontScale
の上書きが無効になっているようでした。
そのため Dialog
を使う場合は別途 content
に対しても CompositionLocalProvider
を使った上書き指定が必要になりそうです。
その他の方法
以下のような方法でも fontScale
を無視させることができるようです。
スポットで無視するような場合には使い勝手がいいのかもしれません。
val TextUnit.nonScaledSp
@Composable
get() = (this.value / LocalDensity.current.fontScale).sp
Text(
text = "Hello Android!",
fontSize = 16.sp.nonScaledSp
)
参考