-
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' 카테고리의 다른 글
3. Compose 함수 및 상태에 대한 이해 (0) 2025.03.26 2. Compose Modifier를 활용한 스타일링 (padding, background 등등) (0) 2025.03.18 1. Compose 기본 UI - Text, TextField, Image, Row, Column, Box (0) 2025.03.18 Compose 학습 이정표 (0) 2025.03.16 안드로이드 Coroutine Flow - 3 (StateFlow) 코드 (0) 2024.12.02