**스티키 헤더(Sticky Header)**는 긴 리스트에서 섹션의 제목을 스크롤 시에도 화면 상단에 고정시켜 사용자가 콘텐츠를 쉽게 파악할 수 있도록 돕는 UI 컴포넌트입니다. 스티키 헤더는 다양한 종류와 스타일로 구현할 수 있으며, 사용자의 요구에 맞게 적절한 방식으로 선택할 수 있습니다. 본 글에서는 스티키 헤더의 종류와 각 방식의 구현 방법을 자세히 설명합니다.
1. 기본 스티키 헤더 (Fixed Sticky Header)
가장 기본적인 형태의 스티키 헤더는 리스트에서 각 섹션의 첫 번째 항목(헤더)을 고정하여 화면 상단에 표시됩니다. 사용자가 리스트를 스크롤할 때 해당 섹션의 헤더가 화면 상단에 고정되고, 다른 섹션의 헤더가 화면에 나타날 때마다 해당 섹션의 헤더가 새롭게 고정됩니다.
예시: 기본적인 스티키 헤더
@Composable
fun BasicStickyHeader() {
val sections = listOf(
"Fruits" to List(10) { "Fruit #$it" },
"Vegetables" to List(10) { "Vegetable #$it" },
"Meats" to List(10) { "Meat #$it" }
)
LazyColumn {
sections.forEach { (header, items) ->
stickyHeader {
Text(
text = header,
style = MaterialTheme.typography.h6,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
.padding(16.dp)
)
}
items(items) { item ->
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
}
2. 여러 개의 스티키 헤더 (Multiple Sticky Headers)
이 방식은 리스트에 여러 개의 스티키 헤더가 존재할 때 사용됩니다. 예를 들어, 리스트의 앞부분에 고정된 헤더가 있고, 사용자가 스크롤하여 다른 섹션을 지나면 새로운 헤더가 화면 상단에 고정됩니다. 여러 개의 스티키 헤더가 동시에 고정되는 효과를 구현할 수 있습니다.
예시: 여러 개의 스티키 헤더
@Composable
fun MultipleStickyHeaders() {
val sections = listOf(
"Top Section" to List(20) { "Top Item #$it" },
"Middle Section" to List(20) { "Middle Item #$it" },
"Bottom Section" to List(20) { "Bottom Item #$it" }
)
LazyColumn {
sections.forEach { (header, items) ->
stickyHeader {
Text(
text = header,
style = MaterialTheme.typography.h6,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
.padding(16.dp)
)
}
items(items) { item ->
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
}
3. 가변형 스티키 헤더 (Dynamic Sticky Header)
가변형 스티키 헤더는 스크롤에 따라 헤더의 크기나 스타일이 변화하는 방식입니다. 사용자가 스크롤할 때 헤더가 크기가 줄어들거나 커지거나, 색상이 변하는 등의 변화를 주어 더 동적인 UI를 구현할 수 있습니다.
예시: 가변형 스티키 헤더
@Composable
fun CollapsingStickyHeader() {
val sections = listOf(
"Fruits" to List(10) { "Fruit #$it" },
"Vegetables" to List(10) { "Vegetable #$it" },
"Meats" to List(10) { "Meat #$it" }
)
var headerSize by remember { mutableStateOf(100.dp) }
LazyColumn {
sections.forEach { (header, items) ->
stickyHeader {
Box(
modifier = Modifier
.fillMaxWidth()
.height(headerSize)
.background(MaterialTheme.colors.primary)
.padding(16.dp)
) {
Text(
text = header,
style = MaterialTheme.typography.h6,
modifier = Modifier.align(Alignment.Center)
)
}
}
items(items) { item ->
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
LaunchedEffect(Unit) {
snapshotFlow { headerSize }
.collect { newSize ->
headerSize = 50.dp // Example logic for changing header size
}
}
}
4. 그룹화된 스티키 헤더 (Grouped Sticky Headers)
그룹화된 스티키 헤더는 여러 섹션이 그룹화된 형태로, 각 그룹의 헤더가 고정됩니다. 예를 들어, 날짜별로 그룹화된 항목들을 나열할 때 각 날짜마다 고정된 헤더가 표시됩니다.
예시: 그룹화된 스티키 헤더 구현
@Composable
fun GroupedStickyHeader() {
val groupedItems = listOf(
"2025-01-01" to List(10) { "Event #$it" },
"2025-01-02" to List(10) { "Event #$it" }
)
LazyColumn {
groupedItems.forEach { (header, items) ->
stickyHeader {
Text(
text = header,
style = MaterialTheme.typography.h6,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.primary)
.padding(16.dp)
)
}
items(items) { item ->
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
}
}
결론: 스티키 헤더의 다양한 사용 방식
스티키 헤더는 사용자의 스크롤 경험을 향상시키고, 긴 리스트에서 중요한 정보를 쉽게 파악할 수 있도록 돕는 중요한 UI 요소입니다. 기본 스티키 헤더, 여러 개의 스티키 헤더, 가변형 스티키 헤더, 그룹화된 스티키 헤더 등 다양한 방식으로 구현할 수 있습니다.