안드로이드 코틀린

[Kotlin][Android] Jetpack Compose로 system bar 색 변경하기

teamnova 2022. 9. 27. 12:00
728x90

안녕하세요.

오늘은 XML 파일을 수정하지 않고 Compose를 사용하여 상태 표시줄과 탐색 표시줄 색상을 변경하는 방법을 알아보겠습니다. 

 

Jetpack Compose 이전에는 system bar색상을 지정하기 위해 일반적으로 다음 themes.xml과 같이 파일을 수정했습니다.

 

<resources>
    <style name="Theme.BarColors" parent="android:Theme.Material.Light.NoActionBar">
        <item name="android:statusBarColor">@color/purple_700</item>
        <item name="android:navigationBarColor">@color/purple_700</item>
    </style>
</resources>

 android:statusBarColor및 android:navigationBarColor속성은 각각 상태 표시줄 색상과 탐색 표시줄 색상에 영향을 줍니다.

 

android:windowLightStatusBar (상태 표시줄의 아이콘을 어둡게 만들기 위해) 또는 android:windowLightNavigationBar(탐색 표시줄과 유사하게 ) 지정할 수 있습니다. (후자는 API 레벨 27이 필요 합니다.)

폴더 themes.xml아래의 다른 파일에서 이 속성을 재정의해야 합니다. values-27이와 같은 속성이 많을 때 매우 지저분한 구조로 이어질 수 있습니다. 어두운 테마를 지원하려면 더욱 복잡해질 수 있습니다. 

 

Compose에는 이를 수행하는 다른 방법이 있습니다.

 

먼저 구현을 위해 Compose를 사용하여 중앙에 텍스트를 표시하는 간단한 화면을 만들어보겠습니다.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		
        setContent {
            BarColorsTheme {
                Surface {
                    Text(
                        modifier = Modifier
                            .fillMaxSize()
                            .wrapContentHeight(),
                        textAlign = TextAlign.Center,
                        style = MaterialTheme.typography.h3,
                        text = "Hello Android!",
                    )
                }
            }
        }
    }
}

 

프로젝트를 새로 만들때 Empty Compose Activity를 선택하면 위에서 사용되는 함수를 사용할 수 있습니다. 

 

private val DarkColorPalette = darkColors(
    primary = Purple200,
    primaryVariant = Purple700,
    secondary = Teal200
)

private val LightColorPalette = lightColors(
    primary = Purple500,
    primaryVariant = Purple700,
    secondary = Teal200
)

@Composable
fun BarColorsTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }

    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}

위 코드는 프로젝트 전체에 대한 적절한 색상 팔레트(어두운 테마 활성화 여부에 따라), 타이포그래피 및 모양을 지정하는 루트 컴포저블 역할을 합니다.

 

@Composable  
fun BarColorsTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {  
	// ...
    val view = LocalView.current  
    if (!view.isInEditMode) {  
        SideEffect {  
            val window = (view.context as Activity).window  
            window.statusBarColor = colors.primary.toArgb()  
            window.navigationBarColor = colors.primary.toArgb()  
  
            WindowCompat.getInsetsController(window, view)  
                .isAppearanceLightStatusBars = darkTheme  
            WindowCompat.getInsetsController(window, view)  
                .isAppearanceLightNavigationBars = darkTheme  
        }  
    }  
	// ...
}

 

변수 WindowCompat값에 따라 상태 표시줄과 탐색 표시줄 아이콘을 밝게 또는 어둡게 만드는 데 사용합니다. 

darkTheme사용의 좋은 이점은 WindowCompat해당 메서드를 실행하기 전에 API 수준을 확인할 필요가 없다는 것입니다. 뒤에서 지원되지 않는 API에는 영향을 미치지 않습니다.

이러한 변경을 수행하고 앱을 실행하면 원하는 효과를 얻을 수 있습니다.

 

Compose로 변경된 시스템 표시줄 색상

 

현재 테마에 맞는 시스템 표시줄 색상