-
Compose 학습 - 1 : 기초안드로이드 학습/Compose 2025. 2. 5. 17:18
링크 : https://developer.android.com/courses/pathways/compose?hl=ko
Jetpack Compose | Android Developers
네이티브 Android UI를 빌드하기 위한 최신 도구 키트인 Compose에 관해 알아봅니다.
developer.android.com
Compose에서는 함수에 @Compose 주석을 추가해야한다.
@Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) }
중간중간 따라 쓰는게 귀찮아서 완료된 코드로 분석
1. onCreate 부분
class PracticeActivity2 : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { BasicsCodelabTheme { MyApp2(modifier = Modifier.fillMaxSize()) } } } }
Activity에서 onCreate로 시작하는 부분이 Compose에서는 이렇게 시작된다.
1. ComponentActivity는 AppCompatActivity보다 더 가볍고 Compose에 더 최적화 되어 있다.
2. enableEdgeToEdge : 이 기능은 상태바와 내비게이션 바 영역까지 콘텐츠를 확장할 수 있도록 해줍니다.
3. Compose에서는 xml이 아닌 Composable 함수로 UI를 구성할 수 있다.
4. BasicsCodelabTheme에서 기본 색상, 폰트 스타일 등을 관리한다.
5. modifier의 fillMaxSize로 화면을 가득 채우도록 지정한다.
2. MyApp2 부분
@Composable fun MyApp2( modifier: Modifier = Modifier ) { var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) } // by remember Surface(modifier) { if (shouldShowOnboarding) { OnboardingScreen(onContinueClicked = { shouldShowOnboarding = false }) } else { Greetings() } } }
1. 외부에서 Modifier를 전달받으면 그것을 사용하고 그렇지 않다면 기본 Modifier를 사용한다.
2. Compose에서 변수를 저장하는 방법은 rememberSaveable을 사용해서 저장한다.
by 키워드를 사용해서 shouldShowOnboarding.value 대신 바로 직접 접근할 수 있게 해준다.
var shouldShowOnboarding by rememberSaveable { mutableStateOf(true) } // by remember
3. OnboardingScreen 함수에는 onContinueClicked를 전달하는데 이게 호출되면 shouldShowOnboarding이 false가 된다.
3. OnboardingScreen()
@Composable fun OnboardingScreen( onContinueClicked: () -> Unit, modifier: Modifier = Modifier ) { Column( modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Welcome to the Basics Codelab!") Button( modifier = Modifier.padding(vertical = 24.dp), onClick = onContinueClicked ) { Text("Continue") } } }
1. onContinueClicked은 앞서 보았든 shouldShowOnboarding를 false로 바꿔주는 함수고 이것을 전달 받아 사용한다.
2. Column은 LinearLayout에서 Horizontal 과 비슷하게 각 Composable 함수를 세로로 나열해준다.
3. Text : TextView
4. Button : Button 이고 onClick으로 수행할 기능을 전달받은 onContinueClicked이다. MyApp2의 shouldShowOnboarding을 false로 바꾸고 화면을 변경한다.
Modifier.padding(vertical = 24.dp)는 위아래로 24dp 만큼의 여백을 제공한다.
Button 내부의 Text는 버튼의 글자다.
4. Greetings()
@Composable private fun Greetings( modifier: Modifier = Modifier, names: List<String> = List(1000) { "$it" } ) { LazyColumn(modifier = modifier.padding(vertical = 4.dp)) { items(items = names) { name -> CustomGreeting(name = name) } } }
1. List를 외부에서 받거나 생성한다. 0부터 999까지 List로 채워진다.
names: List<String> = List(1000) { "$it" }
2. LazyColumn은 RecyclerView와 같은 역할을 한다. padding의 4dp는 가장 위와 가장 아래에 4dp 만큼 간격을 준다.
LazyColumn(modifier = modifier.padding(vertical = 4.dp))
3. items 는 List의 각 항목을 name으로 받아서 UI를 만듦.
items(items = names) → names
5. CustomGreeting()
@Composable fun CustomGreeting(name: String, modifier: Modifier = Modifier) { var expanded by rememberSaveable { mutableStateOf(false) } val extraPadding by animateDpAsState( if (expanded) 48.dp else 0.dp, animationSpec = spring( dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessLow ) ) Surface( color = MaterialTheme.colorScheme.primary, modifier = modifier.padding( vertical = 4.dp, horizontal = 8.dp ) // 이부분은 각 Surface 별로 margin 주는 것과 같다 ) { Row(modifier = Modifier.padding(24.dp)) { Column( modifier = Modifier .weight(1f) .padding(bottom = extraPadding.coerceAtLeast(0.dp)) ) { Text(text = "Hello, ") Text( text = name, style = MaterialTheme.typography.headlineMedium.copy( fontWeight = FontWeight.ExtraBold ) ) } ElevatedButton( onClick = { expanded = !expanded } ) { Text(if (expanded) "Show less" else "Show more") } } } }
1. Greetings에서 정의된 LazyColumn에 각 item 별로 CustomGreeting의 UI를 보여준다.
2. item의 배경은 지정된 MaterialTheme의 primary 색상으로 지정. padding은 각 item 사이의 간격이 좌우 4dp, 위아래 8dp으로 지정.
Surface( color = MaterialTheme.colorScheme.primary, modifier = modifier.padding( vertical = 4.dp, horizontal = 8.dp ) // 이부분은 각 Surface 별로 margin 주는 것과 같다 )
3. weight을 사용해서 Row내에 남은 공간을 가능한 많이 차지하도록 한다.
Column( modifier = Modifier .weight(1f) .padding(bottom = extraPadding.coerceAtLeast(0.dp)) )
extraPadding.coerceAtLeast(0.dp) 이 0보다 작아져도 0으로 변환된다.
4. extrapaddig은 아래의 animationSpec이 0보다 작게 만든다. 그래서 padding에서 coerceAtLeast(0.dp)를 사용한다.
val extraPadding by animateDpAsState( if (expanded) 48.dp else 0.dp, animationSpec = spring( dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessLow ) )
'안드로이드 학습 > Compose' 카테고리의 다른 글
(기초) 1-1. Jetpack Compose : 기존 View 시스템과의 차이 (0) 2025.09.09 5. Compose와 MVVM (0) 2025.04.01 4. Compose Side Effect (0) 2025.03.27 2. Compose Modifier를 활용한 스타일링 (padding, background 등등) (0) 2025.03.18 Compose 학습 이정표 (0) 2025.03.16