핵심 내용
@Composable — 함수를 Composable로 변환하는 애너테이션입니다. Composable 함수는 UI 구성 요소입니다. View를 반환하지 않고 Composition에 요소를 내보냅니다. Composition — Composable 함수 호출로 구축된 UI 트리입니다. Compose는 새 트리를 이전 트리와 비교하고 변경된 부분만 업데이트합니다.
Recomposition — 상태 변경 시 Composable 함수의 재시작입니다. Compose는 각 함수에서 읽는 상태를 추적합니다. 상태가 변경되면 Compose는 해당 상태를 읽는 함수만 재시작합니다 (Smart Recomposition). Recomposition은 낙관적입니다: 여러 번 실행될 수 있으므로 함수는 순수해야 합니다 (부작용 없음). 부작용은 LaunchedEffect 또는 DisposableEffect에 넣습니다. Composable 함수는 suspend가 될 수 없습니다. 다른 Composable 함수에서 호출됩니다. 호출 순서는 보장되지 않습니다 (Compose가 재정렬할 수 있음).
// State Hoisting 및 LazyColumn을 사용한 Composable 예제
@Composable
fun ItemList(
items: List<String>,
onItemClick: (String) -> Unit
) {
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
items(items) { item ->
Card(
modifier = Modifier
.fillMaxWidth()
.clickable { onItemClick(item) }
.padding(8.dp)
) {
Text(
text = item,
style = MaterialTheme.typography.bodyLarge
)
}
}
}
}
@Composable
fun MainScreen() {
var text by remember { mutableStateOf("") }
val items = listOf("Item 1", "Item 2", "Item 3")
Scaffold(
topBar = {
TopAppBar(title = { Text("Compose App") })
}
) { padding ->
ItemList(
items = items,
onItemClick = { selected -> text = selected }
)
}
}Composition — 선언적 트리. Recomposition — 스마트 재시작. IT Sectr은 유형 안정성을 모니터링할 것을 권장합니다 — 불안정한 유형은 과도한 재구성을 유발합니다.
CompositionLocal — Compose에서 암시적 데이터 전달. SwiftUI의 @Environment와 유사합니다. CompositionLocalProvider — 값 설정. current — 읽기. 용도: Theme (MaterialTheme), ContentScale, Density. 정적 CompositionLocal — 변경 없는 구성용. 동적 CompositionLocal — 가변 값 (테마)용. IT Sectr은 전역 구성에는 CompositionLocal, 데이터에는 명시적 매개변수 사용을 권장합니다.
remember — 재구성 사이에 값을 유지합니다. mutableStateOf — 관찰 가능한 상태 생성 (MutableState<T>). 변경 시 재구성을 트리거합니다. State Hoisting — 패턴: 상태를 부모 컴포넌트로 끌어올리고, 자식은 값 + 콜백을 받습니다. State (불변) — 읽기 전용. MutableState — 읽기 + 쓰기. rememberSaveable — 회전/프로세스 종료 시 유지.
State Hoisting — 원칙: state down, events up. 상태는 부모에 저장되고 매개변수를 통해 자식 컴포넌트에 전달됩니다. 자식 컴포넌트는 람다 (콜백)를 통해 변경을 보고합니다. 장점: 재사용성, 테스트 용이성, 단일 진실 공급원. 예: MyTextField가 자체 상태를 저장하는 대신, 부모가 문자열을 저장하고 value + onValueChange를 통해 전달합니다.
derivedStateOf — 계산된 상태, 종속성이 변경될 때만 다시 계산됩니다. 필터링, 변환, 유효성 검사에 사용됩니다. snapshotFlow — State를 Flow로 변환합니다. 반응형 체인에 사용됩니다. collectAsState — Composable 내에서 Flow를 State로 수집합니다. IT Sectr은 계산된 값에는 derivedStateOf, State와 코루틴 연결에는 snapshotFlow 사용을 권장합니다.
Column — 세로 레이아웃 (LinearLayout vertical과 유사). Row — 가로 레이아웃. Box — 스태킹 레이아웃 (FrameLayout과 유사). LazyColumn — 지연 로딩이 있는 세로 스크롤 목록. LazyRow — 가로 스크롤 목록. Scaffold — 주요 화면 구조: TopAppBar, BottomBar, FloatingActionButton, Snackbar. TopAppBar — 상단 바. BottomNavigation — 하단 탐색 (Material 3에서는 NavigationBar). Modifier — 체인: .fillMaxWidth().padding(8.dp).clickable { }. 수정자 순서가 중요 — 각각이 새 래퍼를 만듭니다.
LazyColumn — 가상화된 목록. 보이는 요소만 렌더링합니다. 최적화: 1) key — 항목의 고유 키, 2) contentType — 유형별로 항목 그룹화, 3) itemContent — 항목 내 재구성 최소화, 4) LazyVerticalGrid / LazyHorizontalGrid — 그리드용. LazyLayout — 사용자 정의 지연 레이아웃. Paging 3 + Compose — collectAsLazyPagingItems를 통한 페이징. IT Sectr은 예측 가능한 재구성을 위해 모든 LazyColumn에 key(item) 사용을 권장합니다.
Navigation Compose — 탐색 라이브러리. NavController — 대상 스택 관리. NavHost — 탐색 그래프 컨테이너. composable("route") — 대상 등록. navController.navigate("route") — 탐색. popBackStack() — 뒤로 가기. 인수: composable("detail/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType })). intentFilter를 통한 딥 링크. BottomNavigation — NavController와 통합: NavBarItem → navigate + popUpTo.
다중 백 스택 — 각 BottomNavigation 탭에 대한 별도 백 스택. SavedStateHandle — 프로세스 종료 시 인수 유지. NavArgs — 타입 안전 인수 (Kotlin 2.0+). 딥 링크 — 외부 링크용 URL 스키마. 예측 백 제스처 (Android 14+) — 미리보기가 있는 뒤로 가기 제스처 지원. IT Sectr은 타입 안전성을 위해 NavArgs, BottomNavigation에는 다중 백 스택 사용을 권장합니다.
LaunchedEffect — Composition에서 suspend 블록을 실행합니다. Composition을 떠나면 취소됩니다. keys가 변경되면 다시 시작됩니다. 용도: 데이터 로딩, 타이머, 애니메이션. DisposableEffect — 정리가 필요한 리소스용: onDispose { } — 리스너 구독 해제, 연결 종료. SideEffect — 동기 효과 (매 재구성마다). 용도: 로깅, 비Compose 코드와 동기화. IT Sectr은 데이터 로딩에 LaunchedEffect, 정리에 DisposableEffect 사용을 권장합니다.
| 매개변수 | Jetpack Compose | SwiftUI |
|---|---|---|
| UI 설명 | @Composable 함수 + Modifier | View Protocol + @ViewBuilder |
| 상태 | remember + mutableStateOf | @State, @StateObject |
| 상태 끌어올리기 | State Hoisting | @Binding |
| 목록 | LazyColumn | List |
| 탐색 | NavController + NavHost | NavigationStack (iOS 16+) |
| 효과 | LaunchedEffect, DisposableEffect | .task{}, .onAppear{} |
| 레이아웃 | Column, Row, Box | VStack, HStack, ZStack |
Compose — 함수 + 수정자. SwiftUI — struct + 수정자. 개념은 유사하고 구문은 다릅니다. IT Sectr은 두 프레임워크를 모두 배울 것을 권장합니다 — 하나를 이해하면 다른 하나를 배우기가 쉬워집니다.
rememberCoroutineScope — LaunchedEffect 외부에서 CoroutineScope에 접근 (예: 버튼 클릭 시). snapshotFlow — 체인용으로 State를 Flow로 변환. produceState — 비Compose 소스를 State로 변환. animateFloatAsState 및 animateColorAsState — 효과를 통한 애니메이션. IT Sectr은 UI 이벤트에 rememberCoroutineScope, 자동 로딩에 LaunchedEffect 사용을 권장합니다.
MaterialTheme — Compose의 전역 테마. 색상, 타이포그래피, 모양. MaterialTheme { } — 전체 앱을 감쌉니다. Material3 (M3) — Google 디자인 시스템 2023+. Dynamic Colors — 배경화면에 적응 (Android 12+). TextStyle — 텍스트 구성: fontSize, fontWeight, lineHeight. Shape — 모서리 둥글림. Elevation — 그림자. IT Sectr은 기본적으로 Material3, 최신 기기에는 Dynamic Colors 사용을 권장합니다.
@Composable
fun AppTheme(content: @Composable () -> Unit) {
val colorScheme = if (isSystemInDarkTheme()) {
darkColorScheme(
primary = Color(0xFFBB86FC),
secondary = Color(0xFF03DAC6)
)
} else {
lightColorScheme(
primary = Color(0xFF6200EE),
secondary = Color(0xFF03DAC6)
)
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography(
bodyLarge = TextStyle(fontSize = 16.sp)
)
) { content() }
}animateFloatAsState — Float 값 애니메이션. animateColorAsState — 색상 애니메이션. animateDpAsState — 크기 애니메이션. AnimatedVisibility — .animateEnterExit()로 표시/숨기기. AnimatedContent — 콘텐츠 변경 시 애니메이션 (crossfade, slide). updateTransition — enum 상태 기반 애니메이션. Animatable — Animatable 인터페이스를 통한 사용자 정의 애니메이션. IT Sectr은 목록에 AnimatedVisibility, 화면 전환에 AnimatedContent 사용을 권장합니다.
@Composable
fun AnimatedCounter(count: Int) {
val animatedCount by animateFloatAsState(
targetValue = count.toFloat(),
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
AnimatedContent(targetState = count) { targetCount ->
Text(
text = "$targetCount",
style = MaterialTheme.typography.displayLarge,
modifier = Modifier.animateContentSize()
)
}
}Compose UI Test — Compose 화면 테스트. createComposeRule() — JUnit 규칙. setContent { } — Composable 설정. onNodeWithText, onNodeWithTag, onNodeWithContentDescription — 요소 찾기. performClick, performTextInput, performScrollTo — 작업. assertIsDisplayed, assertTextEquals — 검증. Semantics — 접근성 및 테스트용 Semantics 트리. IdlingResource — 비동기 작업 대기. 스크린샷 테스트 — Papercuts, Roborazzi. IT Sectr은 각 화면에 UI 테스트, ViewModel에 단위 테스트를 권장합니다.
WindowSizeClass — 화면 크기 적응 (Compact, Medium, Expanded). Material3 반응형 레이아웃과 관련. Adaptive Navigation Suite에서 BottomNavigation에서 NavigationRail로 자동 전환에 사용. IT Sectr은 태블릿 및 데스크톱 Compose 적응에 WindowSizeClass 사용을 권장합니다.
Paging 3 + Compose — Google의 페이징 라이브러리. PagingData — 페이지 스트림. PagingConfig — 설정 (pageSize, prefetchDistance). collectAsLazyPagingItems() — Compose에서 수집. PagingSource — 사용자 정의 소스. RemoteMediator — 하이브리드 로딩 (네트워크 + DB). Paging 3는 Compose에서 무한 스크롤 목록의 표준입니다.
자주 묻는 질문
@Composable — UI 함수용 애너테이션. Composable 함수 호출이 Composition을 형성합니다. Recomposition — 상태 변경 시 재시작.
State Hoisting — 상태를 부모로 끌어올리기. State down, events up. 재사용 가능하고 테스트 가능한 컴포넌트.
Recomposition — 상태 변경 시 Composable 함수 재시작. Smart Recomposition — 최소 함수 세트.
NavController — 대상 스택. NavHost — 그래프 컨테이너. composable("route") — 등록. navigate() — 전환.
LaunchedEffect — 자동 취소가 있는 suspend 블록. DisposableEffect — onDispose 정리가 있는 리소스.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.