@Composable
fun SimpleList() {
// We save the scrolling position with this state
val scrollState = rememberScrollState()
Column(Modifier.verticalScroll(scrollState)) {
repeat(100) {
Text("Item #$it", style = MaterialTheme.typography.subtitle1)
}
}
}
그래서 rememberScrollState로 현재 위치를 저장해주고,
verticalScroll을 추가해주어 스크롤이 가능하도록 한다.
이제 모든 아이템을 확인할 수 있게 되었다.
하지만 이렇게 만들게 되면 생성될 때 화면 밖의 모든 아이템을 한번에 생성하게 되므로
퍼포먼스 면에서 떨어진다.
LazyList 만들기
그래서 compose로 LazyList (LazyColumn, LazyRow) 를 제공한다.
기존의 리사이클러뷰와 유사한 기능을 한다.
차이점으로는 리사이클러뷰는 뷰를 재사용하는 반면에 LazyList는 compose를 재사용하지 않는다.
@Composable
fun SimpleLazyList() {
// We save the scrolling position with this state
val scrollState = rememberLazyListState()
LazyColumn(state = scrollState) {
items(100) {
Text("Item #$it", style = MaterialTheme.typography.subtitle1)
}
}
}
위와 같이 LazyColumn을 통해 아까 만들었던 UI와 동일한 UI을 좀더 효율적으로 만들 수 있다.
LazyList는 블록 내부에 LazyListScope 를 제공하여 이 곳에 item 들을 넘겨줌으로써 레이아웃을 만들 수 있다.
@Composable
fun LazyList() {
// We save the scrolling position with this state
val scrollState = rememberLazyListState()
LazyColumn(state = scrollState) {
item {
Text(text = "First item")
}
// Add 5 items
items(5) { index ->
Text(text = "Item: $index")
}
// Add another single item
item {
Text(text = "Last item")
}
}
}
예시로 item 여러개를 넣어보면
이런식으로 잘 표시되는 것을 확인할 수 있다.
@Composable
fun LazyList() {
// We save the scrolling position with this state
val scrollState = rememberLazyListState()
LazyColumn(state = scrollState,
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
item {
Text(text = "First item")
}
// Add 5 items
items(5) { index ->
Text(text = "Item: $index")
}
// Add another single item
item {
Text(text = "Last item")
}
}
}
UI를 좀 더 자연스럽게 하기 위하여
contentPadding 으로 리스트 전체의 패딩을,
verticalArrangement 으로 아이템 사이 간의 간격을 지정해줄 수 있다.
가장자리에서 좀 더 떨어지고 아이템 사이의 간격이 넓어진 것을 확인할 수 있다.
LazyList의 더 자세한 기능(페이징, 헤더 등..) 과 LazyListScope에 대한 설명은
이제 코일을 사용할 수 있게 해주는 rememberImagePainter 을 사용하여 외부 이미지를 가져온다.
잘 불러와진 것을 확인할 수 있다.
List scrolling
리스트에서 스크롤 위치를 수동으로 제어할 수 있다.
위에서 리스트들을 만들 때 크게 활용하지 않은 rememberLazyListState 를 활용하여
그 위치로 이동시켜준다.
@Composable
fun ScrollingList() {
val listSize = 100
// We save the scrolling position with this state
val scrollState = rememberLazyListState()
// We save the coroutine scope where our animated scroll will be executed
val coroutineScope = rememberCoroutineScope()
Column {
Row {
Button(onClick = {
coroutineScope.launch {
// 0 is the first item index
scrollState.animateScrollToItem(0)
}
}) {
Text("Scroll to the top")
}
Button(onClick = {
coroutineScope.launch {
// listSize - 1 is the last index of the list
scrollState.animateScrollToItem(listSize - 1)
}
}) {
Text("Scroll to the end")
}
}
LazyColumn(state = scrollState) {
items(listSize) {
ImageListItem(it)
}
}
}
}
최상단으로 가는 버튼과 최하단으로 가는 버튼을 추가하고
.animateScrollToItem 를 통해 부드러운 스크롤을 직접 할 수 있다.
scrollToItem 를 사용하면 별도의 애니메이션 없이 바로 스크롤 된다.
단 여기서 스크롤 되는 동안 리스트의 아이템들이 UI 를 만드는, 리스트의 렌더링 과정이 차단되지 않도록 하기위하여
코루틴을 활용하여 비동기로 스크롤해준다.
이제 버튼을 눌러 직접 스크롤 할 수 있다.
이 외에도 다양한 방식으로 LazyList를 사용할 수 있다.
기존의 리사이클러뷰처럼 사용빈도가 상당히 클것이기 때문에 좀 더 자세히 공부해봐야 할 것 같다.