본문 바로가기
안드로이드 공부 노트/Compose(컴포즈)

[Android-Compose] 안드로이드 컴포즈 4편 Lazy lists - LazyColumn, LazyRow

by 지게요 2022. 11. 6.
728x90
반응형

이번 컴포즈의 공부 내용은 xml의 리사이클 러뷰의 역할을 하는 LazyColumn, LazyRow, LazyVerticalGrid, LazyHorizontalGrid이다.

 

# Lazy lists(지연 목록)

- 안드로이드 공식 문서에서는 Lazy lists(지연 목록)은 아래와 같이 설명 하고 있다.

많은 수의 항목이나 길이를 알 수 없는 목록을 표시해야 하는 경우 Column과 같은 레이아웃을 사용하면 모든 항목이 표시 가능 여부와 관계없이 구성되고 배치되므로 성능 문제가 발생할 수 있습니다.
Compose는 구성요소의 표시 영역에 표시되는 항목만 구성하여 배치하는 구성요소 집합을 제공합니다. 이러한 구성요소에는 LazyColumn 및 LazyRow가 포함됩니다.
참고: RecyclerView 위젯을 사용한 경우 이러한 구성 요소는 동일한 원칙을 따릅니다.
이름에서 알 수 있듯이 LazyColumn과 LazyRow의 차이점은 항목을 배치하고 스크롤하는 방향입니다. LazyColumn은 세로로 스크롤되는 목록을 생성하고 LazyRow는 가로로 스크롤되는 목록을 생성합니다.
지연 구성요소는 대부분의 Compose 레이아웃과 다릅니다. 지연 구성요소는 @Composable 콘텐츠 블록 구성요소를 수락하고 앱에서 직접 컴포저블을 내보낼 수 있도록 허용하는 대신 LazyListScope.() 블록을 제공합니다. 이 LazyListScope 블록은 앱에서 항목 콘텐츠를 설명할 수 있는 DSL을 제공합니다. 그런 다음 지연 구성요소가 레이아웃 및 스크롤 위치에 따라 각 항목의 콘텐츠를 추가합니다.

간단하게 정리를 하자면 아래와 같다

1. 많은 수의 데이터들을 목록으로 표시해야 하는 경우 Column, Row와 같은 레이아웃을 사용하면 성능 문제가 발생할 수 있다.

2. 데이터들을 표시 영역에 표시되는 항목만 나타낸다.

3. xml에서 RecyclerView와 똑같은 기능을 한다.

4. LazyColumn과 LazyRow의 차이점은 스크롤 하는 방향이다. (Column 세로 Row 가로)

#  Lazy (Column / Row) 사용법 

package com.example.composeex

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement.Center
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Card
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    private val userDataList: MutableList<UserData> = mutableListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        setContent {
            Column(
                modifier = Modifier.fillMaxSize(),
            ) {
                setData()
                LazyColumn(
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Center
                ) {
                    //item 이용하여 단일 데이터 추가
                    item {
                        Text(
                            text = "첫 번째 데이터",
                            fontSize = 25.sp
                        )
                    }

                    //items 이용하여 여러 데이터 추가
                    items(15) { index ->
                        Text(
                            text = "$index 데이터",
                            fontSize = 25.sp
                        )
                        Divider(
                            color = Color.Gray,
                            thickness = 1.dp
                        )
                    }
                    // 아래와 같이 Data Class를 넘겨 줄 수 있음
                    items(userDataList) { userData ->
                        UserDataScreen(userData)
                    }
                }
            }
        }
    }

    private fun setData() {
        userDataList.add(UserData("김이1", "00"))
        userDataList.add(UserData("김이2", "01"))
        userDataList.add(UserData("김이3", "02"))
        userDataList.add(UserData("김이4", "03"))
        userDataList.add(UserData("김이5", "04"))
        userDataList.add(UserData("김이6", "06"))
        userDataList.add(UserData("김이7", "07"))
        userDataList.add(UserData("김이8", "08"))
        userDataList.add(UserData("김이9", "09"))
    }
    @Composable
    fun UserDataScreen(data: UserData) {
        Card {
            Row(
                Modifier
                    .fillMaxSize()
                    .background(color = Color.White)
                    .padding(15.dp),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Text(
                    textAlign = TextAlign.Center,
                    text = data.name
                )
                Text(text = data.age)
            }
            Divider(
                color = Color.Gray,
                thickness = 1.dp
            )
        }
    }


}

41

 위 코드와 사진 처럼 Lazy 스코프 내에서 itme을 사용하면 단일 데이터가 표시되고 items을 사용하면 여러 데이터가 표시된다.

 

#  Lazy (Column / Row) 속성

※이번 예제는 LazyColumn으로 해보겠다.

@Composable
fun LazyColumn(
    modifier: Modifier = Modifier,
    state: LazyListState = rememberLazyListState(),
    contentPadding: PaddingValues = PaddingValues(0.dp),
    reverseLayout: Boolean = false,
    verticalArrangement: Arrangement.Vertical =
        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
    content: LazyListScope.() -> Unit
)

 

- Modifier : 이 레이아웃(LazyColumn)에 적용할 modifier

 

- LazyListState : 리스트 상태를 제어, 관찰할 때 사용하는 상태 값. offset을 가져오는 프로퍼티, 드래그 이벤트를 가져오는 프로퍼티 등을 사용할 수 있다

 

- PaddingValues : 전체 컨텐츠 주위에 패딩을 추가하고 싶을 때 사용. 첫 번째 또는 마지막 아이템 뒤에 패딩을 추가할 때도 쓸 수 있다. 각 아이템 사이에 간격을 추가하려면 verticalArrangement를 사용한다

 

- reverseLayout : 스크롤, 레이아웃 방향을 반대로 뒤집는 프로퍼티. true면 아이템들이 역순으로 배치된다

 

- verticalArrangement : 레이아웃의 자식들의 세로 배열. 아이템 사이 간격을 추가하고 전체 최소 크기를 채우기에 아이템 개수가 충분하지 않을 때 아이템 배열을 지정할 수 있다

 

- horizontalAlignment : 아이템에 가로 정렬을 적용할 때 사용

 

- flingBehavior : 플링 동작을 설명하는 로직

 

- userControlEnabled : 사용자의 제스처 또는 접근성 작업을 통한 스크롤이 허용되는지 여부. 비활성으로 설정해도 상태를 사용해서 프로그래밍 방식으로 스크롤할 수 있다

 

- content : 내용을 설명하는 블럭. LazyListScope.item()으로 단일 아이템을 추가하거나 LazyListScope.items()를 써서 여러 아이템들을 추가할 수 있다

 

이러한 다양한 속성들이 있으니 필요에 따라 적절하게 사용하면 되겠다.

 

참조
https://developer.android.com/jetpack/compose/lists
https://onlyfor-me-blog.tistory.com/511
반응형