해당 튜토리얼 진행시 다음과 같은 코드와 마주하게 되었다.
@Composable
fun WoofApp(dogs: List<Dog>) {
Scaffold(
topBar = { WoofTopAppBar() }
) {
LazyColumn(contentPadding = it) {
items(dogs) { dogs ->
DogItem(
dog = dogs,
modifier = Modifier.padding(dimensionResource(R.dimen.padding_small))
)
}
}
}
}
Scaffold()와 LazyColumn() 이 둘에 대해 알아보고자 한다.
Scaffold란?
Material Design에서 복잡한 사용자 인터페이스를 위해 표준화된 플랫폼을 제공하는 기본 구조로써, App bar와 Floating Button같은 UI의 여러 부분을 결합해 앱에 일관된 디자인과 분위기를 준다고 공식 문서에 나와있다.
https://developer.android.com/develop/ui/compose/components/scaffold?hl=ko
하위 문서로는
- 앱 바
- 버튼
- 플로팅 작업 버튼
- 카드
- 칩
- 대화상자
- 진행 상태 표시기
- 슬라이더
- 전환
- 하단 시트
- 탐색 창
- 스낵바
- 목록 및 그리드
가 존재하는데 그냥 UI 전체를 통합 결합하여 관리하는 함수라는 느낌이 강하다.
버튼, 카드 등등 몇 개는 그냥 UI 구성 요소로써 이전 튜토리얼에서도 단독으로 사용한 적이 있으니 실질적으로 Scaffold가 있어야 사용이 용이한 녀석은 위 설명에서 나온 앱 바, 플로팅 액션 버튼 그리고 몇가지 뿐일 것이다.
공식 예제를 살펴보면 다음과 같은 예시가 존재한다.
@Composable
fun ScaffoldExample() {
var presses by remember { mutableIntStateOf(0) }
Scaffold(
topBar = {
TopAppBar(
colors = topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.primary,
),
title = {
Text("Top app bar")
}
)
},
bottomBar = {
BottomAppBar(
containerColor = MaterialTheme.colorScheme.primaryContainer,
contentColor = MaterialTheme.colorScheme.primary,
) {
Text(
modifier = Modifier
.fillMaxWidth(),
textAlign = TextAlign.Center,
text = "Bottom app bar",
)
}
},
floatingActionButton = {
FloatingActionButton(onClick = { presses++ }) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
modifier = Modifier.padding(8.dp),
text =
"""
This is an example of a scaffold. It uses the Scaffold composable's parameters to create a screen with a simple top app bar, bottom app bar, and floating action button.
It also contains some basic inner content, such as this text.
You have pressed the floating action button $presses times.
""".trimIndent(),
)
}
}
}
@Composable
public fun Scaffold(
modifier: Modifier = Modifier,
topBar: @Composable () -> Unit = {},
bottomBar: @Composable () -> Unit = {},
snackbarHost: @Composable () -> Unit = {},
floatingActionButton: @Composable () -> Unit = {},
floatingActionButtonPosition: FabPosition = FabPosition.End,
containerColor: Color = MaterialTheme.colorScheme.background,
contentColor: Color = contentColorFor(containerColor),
contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
content: @Composable (PaddingValues) -> Unit
): Unit
Scaffold의 매개변수도 같이 살펴보면 예상한 것과 같이 Scaffold의 요소로써 실질적으로 쓰일 수 있는 것에는 앱 바, 스넥바, 플로팅 작업 버튼, Drawer용 슬롯 같은 것들이고 나머진 내부 요소로 결합시켜 모아서 관리하는 모양새이다.
LazyColumn이란?
LazyColumn 뿐만 아니라 Row, Grids도 존재하는데, 이건 list의 항목들을 표현해내기 위한 컨테이너 사용했었다.
사용해보고 느낀 것은 이게 Recycler View - Adapter - itemLayout을 전부 합쳐버린 녀석이 아닌가 싶은 것이다.
이 Lazy~들은 item을 기반으로 작동하며, item 하나가 자식 Composable에 대응되어 Lazy~Scope내에서 사용할 수 있다.
item
item은 Lazy~ 내부에 컴포저블을 직접 넣고 싶을 때 사용하는 메서드이다.
fun item(key: Any? = null, content: @Composable LazyItemScope.() -> Unit)
item의 LazyItemScope에 있는 컴포저블이 하나의 item으로 인식되어 모두 표시된다.
items
items는 컴포저블을 반복해서 나타내고자 할 때 사용하는 메서드이다.
fun items(
count: Int,
key: ((index: Int) -> Any)? = null,
itemContent: @Composable LazyItemScope.(index: Int) -> Unit
)
itemsIndexed
itemsIndexed는 커스텀한 클래스 설정이 가능하며, 실제 프로젝트에서 자주 사용하는 방식이다.
inline fun <T> LazyListScope.itemsIndexed(
items: List<T>,
noinline key: ((index: Int, item: T) -> Any)? = null,
crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
)
Compose의 LazyLayout들은 RecyclerView와 달리 하위 항목을 재사용하지 않는다.
대신 스크롤에 따라 새로운 Composable 객체를 발행(emit)하여, 비용을 줄이고 성능을 높인다.
https://developer.android.com/develop/ui/compose/lists?hl=ko
'개발 > 안드로이드' 카테고리의 다른 글
rememberSaveable이란 (0) | 2024.05.08 |
---|---|
AnimatedVisibility()와 MutableTransitionState() (0) | 2024.05.07 |
Jetpack Compose 커스텀 그림자 (0) | 2024.05.02 |
Jetpack Compose에서의 State (0) | 2024.04.30 |
Firebase - 구글 로그인 연동 / 이메일 회원가입 (0) | 2024.02.02 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!