제품 소식

Jetpack Compose 2026년 4월 버전의 새로운 기능

전문 길이: 5분
Meghan Mehta
Developer Advocate, Android

오늘 Jetpack Compose 2026년 4월 버전이 안정화되었습니다. 이번 출시에는 핵심 Compose 모듈 버전 1.11 (전체 BOM 매핑 참고), 공유 요소 디버그 도구, 트랙패드 이벤트 등이 포함되어 있습니다. 또한 사용해 보고 의견을 제공해 주시면 감사한 실험용 API도 몇 가지 있습니다.

오늘 출시된 버전을 사용하려면 Compose BOM 버전을 다음으로 업그레이드하세요.

implementation(platform("androidx.compose:compose-bom:2026.04.01"))

Compose 1.11.0의 변경사항

테스트의 코루틴 실행

Compose에서 테스트 타이밍을 처리하는 방식에 대한 주요 업데이트가 도입됩니다. Compose 1.10에서 발표된 선택 기간에 따라 이제 v2 테스트 API가 기본값이며 v1 API는 지원 중단되었습니다. 주요 변경사항은 기본 테스트 디스패처의 변경입니다. v1 API는 코루틴을 즉시 실행하는 UnconfinedTestDispatcher를 사용했지만 v2 API는 StandardTestDispatcher를 사용합니다. 즉, 테스트에서 코루틴이 실행되면 이제 가상 시계가 진행될 때까지 대기열에 추가되고 실행되지 않습니다.

이렇게 하면 프로덕션 조건을 더 잘 모방하여 경합 상태를 효과적으로 제거하고 테스트 모음을 훨씬 더 견고하고 안정적으로 만들 수 있습니다.

테스트가 표준 코루틴 동작과 일치하고 향후 호환성 문제를 방지하려면 테스트 모음을 이전하는 것이 좋습니다. API 매핑 및 일반적인 수정사항은 마이그레이션 가이드를 참고하세요.

공유 요소 개선 및 애니메이션 도구

공유 요소와 Modifier.animatedBounds를 위한 유용한 시각적 디버깅 도구도 추가했습니다. 이제 타겟 경계, 애니메이션 궤적, 일치하는 항목 수 등 내부에서 어떤 일이 일어나고 있는지 정확히 확인할 수 있으므로 전환이 예상대로 작동하지 않는 이유를 훨씬 쉽게 파악할 수 있습니다. 새 도구를 사용하려면 SharedTransitionLayout을 LookaheadAnimationVisualDebugging 컴포저블로 둘러싸면 됩니다. 

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

트랙패드 이벤트

내장 노트북 트랙패드, 태블릿용 부착형 트랙패드, 외부/가상 트랙패드와 같은 트랙패드에 대한 Compose 지원이 개선되었습니다. 이제 기본 트랙패드 이벤트는 일반적으로 PointerType.Mouse 이벤트로 간주되어 마우스와 트랙패드 동작이 사용자 기대에 더 잘 부합하도록 조정됩니다. 이전에는 이러한 트랙패드 이벤트가 PointerType.Touch의 가짜 터치 스크린 손가락으로 해석되어 사용자 환경에 혼란을 야기했습니다. 예를 들어 트랙패드로 클릭하고 드래그하면 선택하는 대신 스크롤됩니다. 최신 Compose 버전에서 이러한 이벤트의 포인터 유형을 변경하면 트랙패드로 클릭하고 드래그해도 더 이상 스크롤되지 않습니다.

또한 API 34부터 플랫폼에서 인식되는 더 복잡한 트랙패드 동작(예: 두 손가락 스와이프, 핀치)에 대한 지원도 추가했습니다. 이러한 동작은 트랙패드에서 더 나은 동작을 할 수 있도록 Modifier.scrollable 및 Modifier.transformable과 같은 구성요소에 의해 자동으로 인식됩니다.

이러한 변경사항을 통해 내장 구성요소 전반에서 트랙패드의 동작이 개선됩니다. 중복된 터치 슬롭이 삭제되고, 더 직관적인 드래그 앤 드롭 시작 동작, 텍스트 필드에서의 더블클릭 및 트리플클릭 선택, 텍스트 필드에서의 데스크톱 스타일 컨텍스트 메뉴가 제공됩니다.

트랙패드 동작을 테스트하기 위해 트랙패드와 함께 사용할 때 앱의 동작을 검증할 수 있는 performTrackpadInput,가 포함된 새로운 테스트 API가 있습니다. 맞춤 동작 감지기가 있는 경우 터치 스크린, 마우스, 트랙패드, 스타일러스를 비롯한 입력 유형 전반에서 동작을 검증하고 마우스 스크롤 휠과 트랙패드 동작을 지원해야 합니다.

beforeAndAfter.webp

컴포지션 호스트 기본값 (Compose 런타임)

compose-runtime을 통해 호스트 수준 서비스를 직접 제공하기 위해 HostDefaultProviderLocalHostDefaultProviderHostDefaultKey, ViewTreeHostDefaultKey가 도입되었습니다. 이렇게 하면 라이브러리가 조회를 위해 compose-ui에 의존할 필요가 없어 Kotlin 멀티플랫폼을 더 잘 지원할 수 있습니다. 이러한 값을 컴포지션 트리에 연결하기 위해 라이브러리 작성자는 compositionLocalWithHostDefaultOf를 사용하여 호스트에서 기본값을 확인하는 CompositionLocal를 만들 수 있습니다.

래퍼 미리보기

Android 스튜디오 맞춤 미리보기는 Compose 미리보기의 콘텐츠가 표시되는 방식을 정확하게 정의할 수 있는 새로운 기능입니다.

PreviewWrapperProvider 인터페이스를 구현하고 새로운 @PreviewWrapper 주석을 적용하면 특정 Theme을 적용하는 등 맞춤 로직을 쉽게 삽입할 수 있습니다. 이 주석은 @Composable 및 @Preview 또는 @MultiPreview로 주석이 지정된 함수에 적용할 수 있으며, 미리보기 기능 전반에서 작동하고 반복되는 코드를 크게 줄여주는 일반적이고 사용하기 쉬운 솔루션을 제공합니다.

class ThemeWrapper: PreviewWrapper {
    @Composable
    override fun Wrap(content: @Composable (() -> Unit)) {
        JetsnackTheme {
            content()
        }
    }
}

@PreviewWrapperProvider(ThemeWrapper::class)
@Preview
@Composable
private fun ButtonPreview() {
    // JetsnackTheme in effect
    Button(onClick = {}) {
        Text(text = "Demo")
    }
}

지원 중단 및 삭제

  • Compose 1.10 블로그 게시물에서 발표한 바와 같이 Modifier.onFirstVisible()이 지원 중단됩니다. 이름으로 인해 오해가 발생하는 경우가 많았으며, 특히 스크롤 중에 여러 번 트리거되는 지연 로드 레이아웃에서 그러했습니다. 특정 사용 사례 요구사항에 맞게 표시 상태를 더 정확하게 수동으로 추적할 수 있는 Modifier.onVisibilityChanged()로 마이그레이션하는 것이 좋습니다.
  • TextFields의 D패드 탐색이 이제 항상 기본적으로 사용 설정되므로 ComposeFoundationFlags.isTextFieldDpadNavigationEnabled 플래그가 삭제되었습니다. 새 동작은 게임패드나 TV 리모컨의 D패드 이벤트가 먼저 지정된 방향으로 커서를 이동하도록 합니다. 커서가 텍스트 끝에 도달한 경우에만 포커스가 다른 요소로 이동할 수 있습니다.

예정된 API

예정된 Compose 1.12.0 출시에서 compileSdk이 compileSdk 37로 업그레이드되며, AGP 9와 Compose를 사용하는 모든 앱과 라이브러리가 이 요구사항을 상속받습니다. Compose는 최신 Android 기능에 액세스할 수 있도록 새로운 compileSdks를 신속하게 채택하는 것을 목표로 하므로 최신 출시 버전을 최신 상태로 유지하는 것이 좋습니다. 다양한 API 수준에서 지원되는 AGP 버전에 관한 자세한 내용은 여기에서 문서를 확인하세요

Compose 1.11.0에서는 다음 API가 @Experimental로 도입되었으며, 앱에서 이를 살펴보고 의견을 보내주시기 바랍니다. @Experimental APIs는 초기 평가 및 의견을 위해 제공되며 향후 출시에서 크게 변경되거나 삭제될 수 있습니다.

스타일 (실험용)

스타일 지정을 위한 새로운 실험용 파운데이션 API가 도입됩니다. 스타일 API는 기존에 수정자를 사용하여 실행했던 구성요소의 시각적 요소를 맞춤설정하는 새로운 패러다임입니다. 간단한 상태 기반 스타일 지정과 애니메이션 전환을 통해 스타일 지정이 가능한 표준 속성 세트를 노출하여 더 깊고 쉬운 맞춤설정을 지원하도록 설계되었습니다. 이 새로운 API를 통해 이미 성능 이점을 확인하고 있습니다. 스타일 API가 안정화되면 Material 구성요소에서 스타일을 채택할 계획입니다.

눌린 상태 스타일 배경을 재정의하는 기본 예는 다음과 같습니다.

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}
styles.webp

문서를 확인하고 여기에서 버그를 신고하세요.

MediaQuery (실험적)

새로운 mediaQuery API는 UI를 환경에 적응시키는 선언적이고 성능이 우수한 방법을 제공합니다. 복잡한 정보 검색을 UiMediaScope 내의 간단한 조건으로 추상화하여 필요할 때만 리컴포지션이 발생하도록 합니다.

키보드 유형, 포인터 정밀도와 같은 기기 기능부터 창 크기, 자세와 같은 컨텍스트 상태에 이르기까지 다양한 환경 신호를 지원하므로 깊이 있는 반응형 환경을 빌드할 수 있습니다. 성능은 derivedMediaQuery에 내장되어 고빈도 업데이트를 처리하며, 범위를 재정의하는 기능을 통해 하드웨어 구성 전반에서 테스트와 미리보기를 원활하게 진행할 수 있습니다. 이전에는 기기가 데스크톱 모드인지와 같은 특정 기기 속성에 액세스하려면 많은 상용구를 작성해야 했습니다. 

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

이제 UIMediaQuery를 사용하여 mediaQuery 구문을 추가하여 기기가 탁자 모드인지와 같은 기기 속성을 쿼리할 수 있습니다.

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

문서를 확인하고 여기에서 버그를 신고하세요.

그리드 (실험용)

Grid는 Jetpack Compose에서 복잡한 2차원 레이아웃을 빌드하기 위한 강력한 새 API입니다. Row과 Column은 선형 디자인에 적합하지만 Grid은 스크롤 가능한 목록의 오버헤드 없이 화면 수준 아키텍처와 복잡한 구성요소에 필요한 구조적 제어를 제공합니다. Grid를 사용하면 트랙, 간격, 셀을 사용하여 레이아웃을 정의할 수 있으며 Dp, 백분율, 내재된 콘텐츠 크기, 유연한 'Fr' 단위와 같은 친숙한 크기 조정 옵션을 제공합니다. 

@OptIn(ExperimentalGridApi::class)
@Composable
fun GridExample() {
    Grid(
        config = {
            repeat(4) { column(0.25f) }
            repeat(2) { row(0.5f) }
            gap(16.dp)
        }
    ) {
        Card1(modifier = Modifier.gridItem(rowSpan = 2)
        Card2(modifier = Modifier.gridItem(colmnSpan = 3)
        Card3(modifier = Modifier.gridItem(columnSpan = 2)
        Card4()
    }
}

항목을 자동으로 배치하거나 여러 행과 열에 명시적으로 걸쳐 배치하여 정확도를 높일 수 있습니다. 무엇보다도 적응성이 뛰어나 그리드 트랙과 스팬을 동적으로 재구성하여 탁자 모드나 방향 변경과 같은 기기 상태에 대응할 수 있으므로 폼 팩터 전반에서 UI가 멋지게 표시됩니다.

Grid.gif

문서를 확인하고 여기에서 버그를 신고하세요. 

FlexBox (실험적)

FlexBox는 고성능 적응형 UI를 위해 설계된 레이아웃 컨테이너입니다. 사용 가능한 컨테이너 크기에 따라 항목 크기와 공간 분배를 관리합니다.  래핑 (wrap) 및 항목의 다축 정렬 (justifyContent, alignItems, alignContent)과 같은 복잡한 작업을 처리합니다. 항목이 컨테이너를 채우기 위해 확장 (grow)되거나 축소 (shrink)될 수 있습니다. 

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}
AnimationGif.gif

문서를 확인하고 여기에서 버그를 신고하세요.

새 SlotTable 구현 (실험)

이번 출시에서는 기본적으로 사용 중지된 SlotTable의 새로운 구현이 도입되었습니다. SlotTable는 Compose 런타임이 컴포지션 계층 구조의 상태를 추적하고, 무효화/리컴포지션을 추적하고, 기억된 값을 저장하고, 런타임에 컴포지션의 모든 메타데이터를 추적하는 데 사용하는 내부 데이터 구조입니다. 이 새로운 구현은 주로 무작위 수정과 관련된 성능을 개선하기 위해 설계되었습니다.

새로운 SlotTable를 사용해 보려면 ComposeRuntimeFlags.isLinkBufferComposerEnabled를 사용 설정하세요. 

지금 바로 코딩을 시작하세요.

Jetpack Compose에는 흥미로운 새 API가 많이 있으며 앞으로 더 많은 API가 제공될 예정이므로 Jetpack Compose로 이전하기에 지금이 가장 좋은 시기입니다.  언제나 그렇듯 의견과 기능 요청 (특히 아직 개발 중인 @Experimental 기능에 관한 의견)을 소중하게 생각합니다. 여기에서 제출해 주세요. 즐겁게 작성해 보세요.

작성자:

계속 읽기