제품 소식

Jetpack Compose 2026년 4월 출시의 새로운 기능

읽는 데 5분
Meghan Mehta
Android Developer Advocate

오늘 Jetpack Compose 2026년 4월 출시가 안정화되었습니다. 이 출시에는 버전 1.11의 핵심 Compose 모듈 (전체 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.scrollableModifier.transformable과 같은 구성요소에서 자동으로 인식되어 트랙패드에서 더 나은 동작을 제공합니다.

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

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

beforeAndAfter.webp

구성 호스트 기본값 (Compose 런타임)

HostDefaultProviderLocalHostDefaultProviderHostDefaultKey, ViewTreeHostDefaultKey를 도입하여 compose-runtime을 통해 호스트 수준 서비스를 직접 제공합니다. 이렇게 하면 라이브러리가 조회를 위해 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 출시에서는 compileSdkcompileSdk 37로 업그레이드되며 AGP 9와 Compose에 종속된 모든 앱 및 라이브러리가 이 요구사항을 상속합니다. Compose는 최신 Android 기능에 액세스할 수 있도록 새 compileSdks를 신속하게 채택하는 것을 목표로 하므로 최신 출시 버전을 최신 상태로 유지하는 것이 좋습니다. 다양한 API 수준에서 지원되는 AGP 버전에 관한 자세한 내용은 여기에서 문서를 확인하세요. 

Compose 1.11.0에서는 다음 API가 @Experimental로 도입되며 앱에서 이러한 API를 탐색할 때 의견을 들려주시기 바랍니다. @Experimental APIs는 초기 평가 및 의견을 위해 제공되며 향후 출시에서 크게 변경되거나 삭제될 수 있습니다.

스타일 (실험용)

_스타일 지정_을 위한 새로운 실험용 Foundation 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입니다. RowColumn은 선형 디자인에 적합하지만 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 기능)을 소중하게 생각합니다. 여기에서 신고해 주세요. 즐겁게 작성해 보세요.

작성자:

계속 읽기