본문 바로가기

Android/Jetpack Compose

[Jetpack Compose] LazyVerticalGrid에 대한 StickyHeader 만들기

728x90
반응형

다음의 XML 코드로 된 GridView에 대해 StickyHeader UI Effect를 만들고 싶었다.

<GridView>
    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />

    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />

    <Title of Grid content in a single row />
    <Grid content arranged in the form of n * 3 />
</GridView>

 

하지만 Jetpack Compose는 StickyHeader를 LazyColumn에 대해서만 제공하고 있었고,
Vertical Scroll(수직 스크롤)이 있는 Column 주변에 LazyColumnGrid를 사용하려 했더니 다음과 같은 오류가 발생했다.

 

it's wrong to nest two scrollable views in the same direction.

 

심지어 item{}에 대해 <Title of Grid />를 사용해봤지만 item{}은 GridView 내의 아이템이 될 뿐이고 하나의 행이 되지 않았다.

 

 

그래서 LazyVerticalGrid에 대해서 구현하려면 직접 확장 함수를 만들어야 했고,

직접 만든 StickyHeader 확장 함수는 다음과 같다.

fun LazyGridScope.header(
    content: @Composable LazyGridItemScope.() -> Unit
) {
    item(span = { GridItemSpan(this.maxLineSpan) }, content = content)
}

여기서 this.maxLineSpan은 header(헤더)의 전체 너비가 된다.

 

그래서 이 헤더를 활용해서 다음과 같이 구현할 수 있다.

LazyVerticalGrid(
    ...
) {
    header {
        Text("헤더 제목1")
    }
    items(count = n * 3) {
        GridItem() 
    }

    header {
        Text("헤더 제목2")
    }
    items(count = n * 3) {
        GridItem() 
    }
    ...
}

 

이렇게 해서 나온 UI는 다음과 같았다.

 

 

 

덤으로, GridCell의 오프셋(GridCell 간격)을 정하는 확장 함수를 다음과 같이 만들어볼 수도 있다.

fun LazyGridScope.offSetCells(count: Int) {
    item(span = { GridItemSpan(count) }) {}
}

...

LazyVerticalGrid(
   ...
) {
    offsetCells(count = 3)
   ...
}

 

 

후기

StickyHeader는 @ExperimentalApi이기 때문에 언제 없어질지 모르는데, 유용하게 쓰이는 UI이라서 언제쯤 정식으로 제공되는 Api가 될지 궁금해진다..

 

 

출처

https://stackoverflow.com/questions/68886848/how-can-i-add-a-stickyheader-to-lazyverticalgrid-like-lazycolumn-in-jetpack-comp

 

 

 

구독과 공감은 블로그 운영에 큰 힘이 됩니다!
긍정적인 댓글 남겨주시면 감사드리며,
보완해야 할 점이 있으면 댓글로 남겨주셔도 좋습니다!

728x90
반응형