본문 바로가기
Development/Android

[Android/안드로이드] Jetpack Compose - 폰트 크기 고정하기

by du.it.ddu 2024. 6. 17.
반응형

모바일 앱은 접근성 강화를 위해 시스템의 폰트 설정에 따라 동적으로 폰트 크기가 변화하도록 권장하고 있습니다.

그러나 앱을 개발하다보면, UI 처리의 용이성을 위해 폰트 크기를 고정으로 하고싶은 욕구가 뿜뿜하곤 합니다.

기존의 안드로이드 앱에서는 DP 사이즈를 사용해서 이를 해소하곤 했습니다만, Compose에서는 DP 사이즈의 사용이 불가합니다.
대신에 TextUnit 이라는 것을 사용하게 되며, 일반적으로 SP를 사용하게 됩니다.

https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/TextUnit

 

TextUnit  |  Android Developers

androidx.compose.desktop.ui.tooling.preview

developer.android.com

SP란, Scale-Independent Pixels 를 의미하며, 시스템 설정의 영향을 받습니다.
따라서 같은 값의 SP여도 어느 사용자는 기대보다 작게, 어느 사용자는 기대보다 크게 보여지게 되어 UI가 달라지고 깨지는 경우도 발생합니다.

이런 불상사를 막기 위해 일부 UI에서는 시스템 설정과 무관한 크기로 보여졌으면 하는 니즈가 종종 있습니다.
이럴때 Compose에서 어떻게 할 수 있는지 알아보겠습니다.


첫번째, DP를 사용하여 SP로 만드는 유틸 코드를 활용합니다. 이를테면 다음과 같습니다.

@Composable
fun dpToSp(dp: Dp): TextUnit = with(LocalDensity.current) { dp.toSp() }

이렇게 하면 화면 밀도에 해당하는 DP 사이즈를 SP로 변환하기 때문에 시스템 폰트 설정에 영향을 받지 않을 수 있습니다.

 

두번째, 현재 폰트 크기를 폰트 시스템 설정으로 나누어서 1배로 만들어 사용합니다. 이를테면 다음과 같습니다.

val Int.nonScaledSp: TextUnit
    @Composable
    get() = (this / LocalDensity.current.fontScale).sp

이렇게 하면 증가한 Scale 만큼 font 사이즈를 다시 조정해주기 때문에 시스템 폰트 설정 값이 제거된 값으로 사용할 수 있습니다.

 

세번째, CompositionLocalProvider를 사용해서 LocalDensity의 fontScale 값을 고정합니다. 이를테면 다음과 같습니다.

CompositionLocalProvider(
    LocalDensity provides Density(
        density = LocalDensity.current.density,
        fontScale = 1f
    )
) {
    // Composables
}

이렇게 하면, CompositionLocalProvider 내의 Composable들은 시스템 폰트 설정의 영향을 받지 않은 채로 SP를 사용할 수 있습니다.
단, 모든 텍스트의 사이즈를 고정하면 접근성에 있어서 좋지 않은 사용자 경험이 될 수 있으므로 주의해야 합니다.

반응형