일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 백준
- power menu
- 힐트
- Sticky Header RecyclerView
- power menu 라이브러리
- 안드로이드 무한 스크롤
- 스레드 vs 코루틴
- runCatching
- android orbit
- 코루틴 공식문서
- 코루틴 공식 문서
- 안드로이드 컴포즈
- Thread vs Coroutine
- Android Compose Navigation
- RecyclerView Sticky Header
- 코루틴
- Android Compose
- Hilt 에러
- 코틀린 에러 핸들링
- android compose orbit
- Unsupported metadata version. Check that your Kotlin version is >= 1.0: java.lang.IllegalStateException
- Kotlin Serialization
- 안드로이드 커스텀 뷰
- hilt
- viewmodel
- 백준 2615
- AAC ViewModel
- BOJ
- Coroutine
- Android Custom View
- Today
- Total
Beeeam
컴포즈 공부 4일차 (code lab) 본문
오늘은 코드랩를 진행하면서 공부하였다. 코드랩은 밑의 링크에서 진행해 볼 수 있다.
https://developer.android.com/codelabs/jetpack-compose-basics?hl=ko#1
Jetpack Compose 기초 | Android Developers
이 Codelab에서는 Compose의 기본사항을 알아봅니다.
developer.android.com
몇 가지 빼고는 다 앞에서 공부 했던 것들이라서 복습하는 느낌이 많이 들었다.
기본적으로 컴포즈로 프로젝트를 생성하면 다음과 같은 형식의 코드를 볼 수 있다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BasicsCodelabTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
Surface의 본문의 Greeting 컴포저블이 뷰 컴포넌트를 정의하고 있고 이를 Activity에서 실행하는 것이다. 컴포즈는 사용자가 정의한 뷰를 미리보기 할 수 있는 기능을 지원한다. 미리보기 기능은 다음의 코드를 선언하면 사용할 수 있다.
@Preview(showBackground = true, name = "Text preview")
@Composable
fun DefaultPreview() {
BasicsCodelabTheme {
Greeting(name = "Android")
}
}
modifier 인자를 사용하여 컴포넌트의 위치, 크기, 패딩 등을 정의할 수 있다.
@Composable
private fun Greeting(name: String) {
Surface(color = MaterialTheme.colorScheme.primary) {
Text(text = "Hello $name!", modifier = Modifier.padding(24.dp))
}
}
위와 같이 선언하면 Text의 모든 면(Top, Bottom, Start, End)에 패딩이 적용된 것을 확인할 수 있다.
Row와 Column을 사용하여 레이아웃에 컴포넌트들을 정렬할 수 있다.
modifier의 fillMaxWidth을 사용하면 해당 컴포넌트의 가로 크기를 화면에 꽉 채울 수 있다. 그리고 weight를 사용하면 컴포넌트의 크기에 가중치를 줘서 가중치가 없는 컴포넌트를 밀어내서 사용할 수 있는 모든 공간을 사용할 수 있다.
이를 이용하여 다음과 같은 뷰를 구현할 수 있다.
@Composable
fun Greeting(text: String) {
Surface(
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp),
) {
Row(modifier = Modifier.fillMaxWidth().padding(24.dp)) {
Column(Modifier.weight(1f)) {
Text(text = "Hello")
Text(text = text)
}
ElevatedButton(
onClick = { /*TODO*/ },
) {
Text(text = "Show more")
}
}
}
}
컴포넌트들을 가로로 정렬하는 Row에 fillMaxWidth를 사용하여 화면의 가로를 꽉 채우게 한 다음 텍스트를 열로 정렬하는 Column에 가중치를 줘서 가중치가 없는 버튼을 오른쪽으로 밀어내서 위와 같은 컴포넌트를 구현할 수 있다.
컴포즈의 상태는 remember 키워드를 사용하여 mutableStateOf로 감싸서 만들 수 있다.
ex)
val expanded = remember { mutableStateOf(false) }
// 또는
val expanded by remember { mutableStateOf(false) }
번외)
상태는 위와 같이 두 가지 방법으로 표현이 가능하다. 그럼 둘의 차이점은 뭘까
= 연산자를 사용하여 상태를 만들면 해당 객체에 직접 접근할 수 없다.
하지만 by 키워드를 사용하여 상태를 만들면 해당 객체에 직접 접근할 수 있다.
= 연산자를 사용하면 expanded.value = true 이 처럼 접근해야 한다.
by 키워드를 사용하면expanded = true 이 처럼 접근할 수 있는 차이가 있다.
컴포즈에서 상태를 관리하는 것은 중요하다. 한 컴포저블에서 많은 상태를 관리하게 되면 해당 컴포저블은 재사용성이 떨어진다. 이 때문에 상태 호이스팅을 사용한다. 이는 상태를 들어올린다는 뜻으로 여러 컴포저블들이 사용하거나 수정하는 상태는 상위 컴포저블에서 관리하도록 하는 것이다.
@Composable
fun OnboardingScreen(modifier: Modifier = Modifier) {
// TODO: This state should be hoisted
var onBoardingState by remember { mutableStateOf(true) }
Column(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Welcome to the Basics Codelab!")
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = { onBoardingState= false }
) {
Text("Continue")
}
}
}
위의 온보딩 컴포저블을 onBoardingState 상태의 값에 따라 보여줄 지 말지를 결정해야한다. 이를 구현하기 위해 다음과 같이 상위 컴포저블에서 상태를 관리하게 하였다.
@Composable
fun MyApp() {
var onBoardingState by remember { mutableStateOf(true) }
if (onBoardingState) {
OnboardingScreen(onContinueClick = { onBoardingState = false })
} else {
Greetings()
}
}
@Composable
fun OnboardingScreen(onContinueClick: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text("Welcome to the Basics Codelab!")
Button(
modifier = Modifier.padding(vertical = 24.dp),
onClick = onContinueClick,
) {
Text("Continue")
}
}
}
이 처럼 상위 컴포저블에서 상태를 관리하면서 수정하고자 하면 하위 컴포저블에 람다로 전달하여 상태 호이스팅을 하면 컴포저블의 재사용성을 높일 수 있다.
lazyColumn 만들기
이건 코드랩 진행하면서 처음 접한 개념이다.
xml로 스크롤을 할 수 있는 리스트를 구현할 때는 RecyclerView를 사용하였는데 컴포즈에서는 lazyColumn을 사용하여 구현할 수 있다.
@Composable
fun Greetings() {
val names = List(100) { "$it" }
Surface(modifier = Modifier.padding(vertical = 4.dp)) {
LazyColumn {
items(items = names) { name ->
Greeting(text = name)
}
}
}
}
LazyColumn 본문에 items의 인자로 사용하고자 하는 리스트를 넣고 본문에 리스트의 아이템 뷰에 해당하는 컴포저블을 넣어주면 구현된다.
애니메이션은 animateDpAsState 컴포저블을 사용하여 구현할 수 있다. 클릭했을 때 펼쳐줄 크기를 정의한 변수를 다음과 같이 정의하면 애니메이션을 적용할 수 있다.
val extraPadding by animateDpAsState(
if (expanded) 48.dp else 0.dp,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
spring 말고 다른 애니메이션들도 적용이 가능하다.
위의 뷰에서 버튼의 텍스트를 “Show more” 형식으로 정의해놨다. 이런 하드코딩은 좋지 않기 때문에 이를 app/src/res/values/strings.xml 파일에 다음과 같이 정의하고 사용하는게 좋다.
<string name="show_less">Show less</string>
<string name="show_more">Show more</string>
// 사용
stringResource(R.string.show_less)
stringResource(R.string.show_more)
작성 코드
https://github.com/BEEEAM-J/compose_code_lab
GitHub - BEEEAM-J/compose_code_lab
Contribute to BEEEAM-J/compose_code_lab development by creating an account on GitHub.
github.com
'Android' 카테고리의 다른 글
LazyColumn (1) | 2024.01.23 |
---|---|
컴포즈 내비게이션 (2) | 2023.12.26 |
컴포즈 공부 3일차 (1) | 2023.11.28 |
컴포즈 공부 2일차 (1) | 2023.11.26 |
컴포즈 공부 1일차 (코드 형식 및 연습) (1) | 2023.11.26 |