1. 개요

- 컴포저블 트리를 통해 데이터를 암묵적으로 전달하는 매커니즘

- Prop Drilling을 막을 수 있음

  ※ Prop Drilling : 부모 -> 자식으로 데이터를 넘기기 위해 매개변수에 담아 보내게 되면, 중간단계의 자식컴포저블들은 해당 매개변수를 전혀 사용하지 않음에도 전달을 위해 매개변수를 추가해야하는 문제

 

2. CompositionLocal의 종류

1) Android 플랫폼 및 UI 환경 (androidx.compose.ui.platform)

- LocalContext.current : 현재 Android Context 객체 제공(리소스 읽기, Toast 띄우기, Intent 실행 등에 사용)
- LocalLifecycleOwner.current : 현재 컴포저블 영역의 LifecycleOwner를 제공(Lifecycle 이벤트 관찰 시 사용)
- LocalSavedStateRegistryOwner.current : 프로세스 종료 및 재시작 시 상태를 저장하고 복원하는 SavedStateRegistryOwner 제공
- LocalView.current : Compose UI를 호스팅하고 있는 최상위 Android Native View 객체를 제공
- LocalViewConfiguration.current : 터치 슬롭(Touch Slop), 롱프레스 인식 시간, 더블탭 간격 등 UI 터치 및 시스템 제스처 관련 임계 설정값을 제공
- LocalConfiguration.current : 현재 Android Configuration 객체를 제공(화면 방향, 화면 너비/높이(dp), 시스템 언어 등)
- LocalDensity.current : 화면 밀도 정보를 제공(dp ↔ px, sp ↔ px 단위 변환을 수행)
- LocalLayoutDirection.current : 레이아웃 배치 방향을 제공(LTR, RTL)
- LocalFocusManager.current : FocusManager를 제공(키보드 해제나 포커스 이동 관리)
- LocalSoftwareKeyboardController.current : 소프트 키보드(IME)를 수동으로 숨기거나 보여주는 제어기 제공
- LocalInputModeManager.current : 현재 사용자 입력 모드(Touch vs Keyboard/Mouse)를 감지하고 변경
- LocalWindowInfo.current : 현재 창의 포커스 상태(활성화 여부) 및 윈도우 관련 정보를 제공
- LocalUriHandler.current : URL/URI를 외부 웹 브라우저나 관련 앱으로 열어주는 UriHandler를 제공
- LocalClipboardManager.current / LocalClipboard.current : 시스템 클립보드에 텍스트를 복사하거나 붙여넣는 기능을 제공
- LocalHapticFeedback.current : 버튼 터치 시 진동/햅틱 피드백을 발생시키는 HapticFeedback을 제공
- LocalTextToolbar.current : 텍스트 선택 시 나타나는 팝업 툴바(복사, 잘라내기, 붙여넣기 등)를 제어
- LocalFontFamilyResolver.current : Compose 텍스트 엔진이 폰트를 해석하고 로드하는 해상도 인터페이스를 제공
- LocalAutofillTree.current : 양식 자동 완성을 위한 Autofill 트리를 관리
- LocalGraphicsContext.current : Canvas 및 그래픽 레이어 연산을 위한 그래픽 컨텍스트를 제공

 

2) Runtime & 개발 도구 (androidx.compose.runtime)

- LocalInspectionMode.current : 현재 코드 영역이 @Preview 모드인지 여부를 반환(프리뷰 전용 가짜 데이터를 노출할 때 유용)
- LocalCompositeKeyHash.current : 컴포지션 트리 상에서 현재 컴포저블 노드의 고유 키 해시값을 반환

 

3) Material & Material3 테마 (androidx.compose.material3 / material)

- LocalColorScheme.current (Material3) / LocalColors.current (Material2) : 현재 테마에 정의된 색상 팔레트(primary, background, surface 등)를 제공
- LocalTypography.current : 현재 테마에 정의된 타이포그래피(글꼴 스타일 세트: titleLarge, bodyMedium 등)를 제공
- LocalShapes.current : 현재 테마에 정의된 컴포넌트 모서리 모양(small, medium, large 등)을 제공
- LocalContentColor.current : 현재 영역의 기본 전경색(텍스트 및 아이콘 색상)을 제공
- LocalTextStyle.current : 현재 영역 내부 Text 컴포저블에 기본으로 적용되는 TextStyle을 제공
- LocalMinimumInteractiveComponentSize.current : 터치 영역의 최소 크기를 설정(기본 48.dp)
- LocalRippleConfiguration.current (Material3) / LocalRippleTheme.current : 클릭/터치 시 발생하는 리플효과의 색상 및 투명도를 설정
- LocalAbsoluteTonalElevation.current : Surface 컴포넌트의 Elevation에 따른 톤 계산용 절대 고도값을 관리

 

4) Foundation 레이아웃 & 상호작용 (androidx.compose.foundation)

- LocalIndication.current : clickable 컴포넌트에 시각적 피드백(기본 Ripple 등)을 전달
- LocalOverscrollConfiguration.current : 스크롤 영역 바깥으로 당겼을 때 나타나는 오버스크롤 효과를 설정
- LocalPinnableContainer.current : LazyColumn 등에서 화면 밖으로 스크롤되어 재사용/파괴되는 것을 방지하고 특정 항목을 메모리에 고정시킬때 사용
- LocalScrollCaptureInProgress.current : Android 12 이상에서 전체 스크롤 캡처(긴 스크린샷)가 진행 중인지 여부를 제공

 

5) Architecture / Lifecycle / Navigation

- LocalViewModelStoreOwner.current : 현재 컴포저블 위치의 ViewModelStoreOwner를 제공(viewModel() 호출 시 생명주기 범위 결정)
- LocalOnBackPressedDispatcherOwner.current : 시스템 뒤로가기 제어기(OnBackPressedDispatcher)를 제공
- LocalActivityResultRegistryOwner.current : RememberLauncherForActivityResult 등 권한 및 갤러리/카메라 결과 수신을 위한 레지스트리 소유자를 제공

 

6) 더 많은 CompositionLocal

위에는 주로 사용되는 CompositionLocal만 나열해둔 것이며 더 많은 CompositionLocal은 아래의 공식 문서에서 확인 가능

- androidx.compose.ui.platform : https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary?utm_source=android-studio-app&utm_medium=app

- androidx.compose.material3 : https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary?utm_source=android-studio-app&utm_medium=app

 

3. CompositionLocalProvider

- 특정 범위의 하위 트리에 값을 제공하는 컴포저블

 

4. 커스텀 CompositionLocal

CompositionLocal을 만들수도 있음

1) staticCompositionLocalOf

- 값이 거의 바뀌지 않는 경우 사용

  - 값 변경이 드물고 성능이 중요할때 등

  - 테마, 언어, 폰트 등

- 값이 바뀌면 해당 CompositionLoaclProvider 하위 트리의 모든 컴포저블이 무조건 리컴포지션됨

  - .current를 읽지 않은 컴포저블도 전부 리컴포지션

 

2) compositionLocalOf

- 값이 자주 바뀌는 경우 사용(자주 바뀌는 UI의 상태 등)

  - 애니메이션 상태나 사용자 액션에 따라 자주 값이 바뀌는 데이터

- 값이 바뀌면 이 값을 실제로 읽는 컴포저블만 재구성

  - .current를 통해 이 값을 실제로 읽은 컴포저블만 재구성

 

3) 구현 예시

// 1. 선언
val LocalUserName = compositionLocalOf { "기본이름" }

// 2. 제공
@Composable
fun App() {
    CompositionLocalProvider(
        LocalUserName provides "홍길동"
    ) {
        UserProfile()
    }
}

// 3. 사용
@Composable
fun UserProfile() {
    val userName = LocalUserName.current // "홍길동"
    Text(text = userName)
}

 

5. 주의점

- 너무 남발하면 코드 이해가 어려워지므로 트리 전체에서 공통적으로 필요한 값이거나 Prop Drilling이 심한 경우에만 사용해야 함