새 프로젝트 만들기에서 [Empty Activity] 선택

MainActivity에 다음과 같은 코드 자동 생성되어있음
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { // 레이아웃 정의
JetpackCompose_StudyTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
// 구성 가능한 함수: 함수가 내부에서 다른 @Composable 함수 호출 가능
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text( // 지정된 입력 표시 함수
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
JetpackCompose_StudyTheme {
Greeting("Android")
}
}
위 코드 빌드 시 다음과 같은 UI가 생성된다.

여기서 Hello Android!에 배경색을 넣어보려면,
Surface를 사용하면 된다.
💡 Surfase 및 MaterialTheme
- Material Design과 관련된 개념
- Material Design:사용자 인터페이스와 환경을 만드는 데 도움을 주기 위해 Google에서 만든 디자인 시스템
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Surface(color = MaterialTheme.colorScheme.primary) { // Greeting에 배경색 설정
Text( // 지정된 입력 표시 함수
text = "Hello $name!",
modifier = modifier
)
}
}

위의 코드에서는 글자의 배경색만 바꾸었지, 글자의 색상까지 바꿔주진 않았다.
이처럼, Compose Material 구성요소는 앱에 넣고자 하는 공통 기능(예: 텍스트에 적절한 색상 선택)을 처리하여 더 나은 환경을 만들도록 빌드된다.
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text(
text = "Hello $name!",
modifier = modifier.padding(24.dp) // 패딩 수정자 생성
)
}
}

다음 코드 추가
@Composable
fun MyApp(modifier: Modifier = Modifier) { // 빈 수정자가 할당되는 수정자 매개변수를 포함
Surface(modifier = modifier, color = MaterialTheme.colorScheme.background) {
Greeting("Android")
}
}
MyApp 컴포저블을 재사용하여 코드 중복을 피할 수 있으므로 onCreate 콜백과 미리보기를 정리할 수 있다.
전체 코드
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { // 레이아웃 정의
JetpackCompose_StudyTheme {
MyApp(modifier = Modifier.fillMaxSize())
}
}
}
}
@Composable
fun MyApp(modifier: Modifier = Modifier) { // 빈 수정자가 할당되는 수정자 매개변수를 포함
Surface(modifier = modifier, color = MaterialTheme.colorScheme.background) {
Greeting("Android")
}
}
// 구성 가능한 함수: 함수가 내부에서 다른 @Composable 함수 호출 가능
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text(
text = "Hello $name!",
modifier = modifier.padding(24.dp) // 패딩 수정자 생성
)
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
JetpackCompose_StudyTheme {
Greeting("Android")
}
}

Column을 사용해 요소들을 세로로 배치하는 코드
@Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Surface(color = MaterialTheme.colorScheme.primary) { Column(modifier = modifier.padding(24.dp)) { Text(text = "Hello") Text(text = "$name") } } }
@Composable
fun MyApp(
modifier: Modifier = Modifier, // 빈 수정자가 할당되는 수정자 매개변수를 포함
names: List<String> = listOf("World", "Compose")
) {
Column(modifier) {
for (name in names) {
Greeting(name = name)
}
}
}

@Preview(showBackground = true, widthDp = 320)
@Composable
fun MyApp(
modifier: Modifier = Modifier, // 빈 수정자가 할당되는 수정자 매개변수를 포함
names: List<String> = listOf("World", "Compose")
) {
Column(modifier = modifier.padding(vertical = 4.dp)) {
for (name in names) {
Greeting(name = name)
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Surface(
color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(vertical = 4.dp, horizontal = 8.dp)
) {
Column(modifier = modifier.fillMaxWidth().padding(24.dp)) {
Text(text = "Hello")
Text(text = name)
}
}
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Surface(
color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(vertical = 4.dp, horizontal = 8.dp)
) {
Row(modifier = Modifier.padding(24.dp)) {
Column(modifier = Modifier.weight(1f)) {
Text(text = "Hello")
Text(text = name)
}
ElevatedButton(onClick = { /*TODO*/ }) {
Text(text = "Show more")
}
}
}
}

💡 리컴포지션
- Compose 앱
- 구성 가능한 함수를 호출하여 데이터를 UI로 변환함
- 컴포지션
- 데이터가 변경되면 Compose가 새 데이터로 함수를 다시 실행하여 업데이트된 UI를 만드는 것
- Compose는 데이터가 변경된 구성요소만 다시 구성하고,
영향을 받지 않는 구성요소는 다시 구성하지 않고 건너뛰도록 개별 컴포저블에서 필요한 데이터를 확인함
컴포저블에 내부 상태를 추가하려면 mutableStateOf 함수를 사용
💡 mutableStateOf
어떤 값을 보유하고 그 값이 변경될 때마다 UI 업데이트(리컴포지션)를 트리거하는 인터페이스
여러 리컴포지션 간에 상태를 유지하려면 remember를 사용하여 변경 가능한 상태를 기억
💡 remember
리컴포지션을 방지하는 데 사용되므로 상태가 재설정되지 않음
@Composable
fun Greeting(...) {
val expanded = remember { mutableStateOf(false) }
// ...
ElevatedButton(
onClick = { expanded.value = !expanded.value },
) {
Text(if (expanded.value) "Show less" else "Show more")
}
}


@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val expanded = remember { mutableStateOf(false) }
val extraPadding = if (expanded.value) 48.dp else 0.dp
Surface(
color = MaterialTheme.colorScheme.primary,
modifier = modifier.padding(vertical = 4.dp, horizontal = 8.dp)
) {
Row(modifier = Modifier.padding(24.dp)) {
Column(modifier = Modifier
.weight(1f)
.padding(bottom = extraPadding)
) {
Text(text = "Hello")
Text(text = name)
}
ElevatedButton(
onClick = { expanded.value = !expanded.value },
) {
Text(if (expanded.value) "Show less" else "Show more")
}
}
}
}
