Jetpack Compose 기초 #1

BongKu·2024년 1월 26일
0

Android

목록 보기
29/30
post-thumbnail

안드로이드 공식 문서를 보며 Jetpack Compose 에 대해서 공부해보려고 합니다.

https://developer.android.com/codelabs/jetpack-compose-basics?hl=ko#0

안드로이드 스튜디오를 최신 버전으로 업데이트하니, 프로젝트 생성 시 자동으로 Compose를 사용할 수 있게 설정이 되어 있네요.


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeBasicTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Greeting("Android")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    ComposeBasicTheme {
        Greeting("Android")
    }
}

@Composable 이라고 주석으로 이 함수가 UI를 그리는 함수라고 알려줍니다.
그 아래 @Preview 주석은 미리보기 함수입니다.

미리보기는 동일한 파일에 여러개를 만들 수 있습니다.

기존에는 SetContentView에서 xml 파일을 주어 레이아웃을 정의했지만, Compose를 사용할 때는 Compose 함수를 SetContentView 내부에서 호출하게 됩니다.

                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                )

Surface 는 Jetpack Compose에서 UI 구성 요소를 그리는 데 사용하는 함수로, Composable 함수 내부에서 UI 요소를 감싸는 컨테이너 역할을 합니다.

Surface 함수를 사용해서 컨테이너의 색을 변경할 수 있습니다.,

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Surface(
        color = MaterialTheme.colorScheme.primary
    ) {
        Text(
            text = "Hello $name!",
            modifier = modifier,
        )
    }
}

  • 색 변경

    컨테이너의 색을 다음과 같이 변경할 수 있습니다.

    컨테이너의 색이 아닌 텍스트의 색을 변경하려면 어떻게 해야 할까요 ?
    텍스트의 Color 속성을 주면 됩니다.

            Text(
                ...
                color = Color.Green,
            )

  • UI 요소 크기 변경

    크기 변경은 Modifier 속성을 사용하면 됩니다.
    Modifier는 Composable 함수 내에서 사용되며, UI 요소에 적용하여 해당 요소의 모양, 위치, 크기, 스타일 등을 설정하거나 변경할 수 있습니다.

        Surface(
            modifier = modifier.padding(20.dp),
            color = MaterialTheme.colorScheme.primary
        ) {
            Text(
                text = "Hello $name!",
                modifier = modifier.padding(30.dp),
                color = Color.Green,
            )
        }

    위와 같이 modifier 를 통해서 컨테이너와 텍스트의 UI요소를 배치할 수 있습니다.

  • 재사용성

    컴포즈의 장점 중 한가지 인 재사용성 입니다.

    다음과 같이 Greeting 함수를 MyApp 내에서 호출함으로써 MyApp은 Greeting을 포함하는 컴포즈로 만들어지고, 이렇게 함으로써 코드의 중복을 피하고 재사용성을 높일 수 있습니다.

    이렇게 Composable 함수를 사용하면 각 함수가 독립적으로 수정 가능하며, UI 요소의 재사용과 유지 보수성을 향상시킬 수 있습니다.

    ...
    class MainActivity : ComponentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
                ComposeBasicTheme {
                    MyApp(modifier = Modifier.fillMaxSize())
                }
            }
        }
    }
    
    @Composable
    private fun MyApp(modifier: Modifier = Modifier) {
        Surface(
            modifier = modifier,
            color = MaterialTheme.colorScheme.background
        ) {
            Greeting("Android")
        }
    }
    ...
    
  • 열과 행 만들기

Column , Row, Box 를 사용할 수 있습니다.

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Surface(
        color = MaterialTheme.colorScheme.primary
    ) {
        Column(modifier = Modifier.padding(24.dp)) {
            Text(
                text = "Hello ",
                color = Color.Green,
            )
            Text(
                text = "$name!",
                color = Color.Green,
            )
        }
    }
}

또한, Compose는 Kotlin의 다른 함수처럼 사용할 수 있습니다.
다음과 같이 for문을 사용해서 Column에 요소를 추가할 수 있습니다.

@Composable
fun MyApp(
    modifier: Modifier = Modifier,
    names: List<String> = listOf("World", "Compose")
) {
    Column(modifier) {
        for (name in names) {
            Greeting(name = name)
        }
    }
}

속성들을 이용해서 아래와 같이 더 깔끔하게 만들 수 있습니다.

@Composable
fun Greeting(name: String) {
    Surface(
        color = MaterialTheme.colorScheme.primary,
        modifier = Modifier.padding(
            vertical = 4.dp, horizontal = 8.dp
        )
    ) {
        Column(modifier = Modifier.fillMaxWidth().padding(24.dp)) {
            Text(
                text = "Hello ",
                color = Color.Green,
            )
            Text(
                text = "$name!",
                color = Color.Green,
            )
        }
    }
}

  • 버튼 추가

버튼은 다음과 같이 추가할 수 있습니다.

Button(
    onClick = { } // You'll learn about this callback later
) {
    Text("Show less")
}
@Composable
private fun Greeting(name: String) {

    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("Show more")
            }
        }
    }
}

  • 상태 저장

컴포저블 내의 변수에 상태를 저장하는 변수를 둘 수 있습니다.

val expanded = remember { mutableStateOf(false) }

이를 활용하여 이전의 버튼에 적용할 수 있습니다.
상태값을 활용해서 버튼을 펼치고, 텍스트를 변경하게 합니다.

@Composable
private fun Greeting(name: String) {

    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")
            }
        }
    }
}

profile
화이팅

0개의 댓글