[Compose] Modifier Extension - DrawScrollbar

2024. 9. 25. 20:03·📂 Android/Compose
반응형

drawScrollbar 함수는 Modifier 클래스에 대한 확장 함수로, LazyColumn에 커스텀 스크롤바를 그릴 수 있게 해줍니다.

이 함수는 drawBehind를 사용하여 컴포저블의 캔버스에 직접 스크롤바를 그립니다.

 

해당 함수는 아래 이슈를 참고하였습니다.

 

Google Issue Tracker

 

issuetracker.google.com

 

/**
 * LazyColumn을 위한 사용자 정의 스크롤바를 그리기 위한 확장 함수
 *
 * @param state LazyListState로, lazy list의 상태를 포함
 * @param barColor 스크롤바의 색상
 * @param barWidth 스크롤바의 너비
 * @param barBottomPadding 스크롤바의 하단 패딩
 */
 
fun Modifier.drawScrollbar(
    state: LazyListState,
    barColor: Color = Color.Gray,
    barWidth: Dp = 4.dp,
    barBottomPadding: Dp = 0.dp
) = drawBehind {
    val firstVisibleElementIndex = state.layoutInfo.visibleItemsInfo.firstOrNull()?.index
    val lastVisibleElementIndex = state.layoutInfo.visibleItemsInfo.lastOrNull()?.index

    val needScrollbar = state.layoutInfo.totalItemsCount > (lastVisibleElementIndex ?: 0)

    if (needScrollbar) {
        val elementHeight = (this.size.height - barBottomPadding.toPx()) / state.layoutInfo.totalItemsCount
        val scrollbarOffsetY = firstVisibleElementIndex!! * elementHeight
        val scrollbarHeight = (lastVisibleElementIndex!! - firstVisibleElementIndex + 1) * elementHeight

        drawRoundRect(
            color = barColor,
            topLeft = Offset(this.size.width - barWidth.toPx(), scrollbarOffsetY),
            size = Size(barWidth.toPx(), scrollbarHeight),
            cornerRadius = CornerRadius(barWidth.toPx() / 2)
        )
    }
}

 

파라미터 설명

  • state: LazyListState: LazyColumn의 상태를 포함하며, 현재 보이는 아이템 정보 등을 가지고 있습니다.
  • barColor: Color: 스크롤바의 색상을 지정합니다.
  • barWidth: Dp: 스크롤바의 너비를 지정합니다.
  • barBottomPadding: Dp: 스크롤바의 하단 패딩을 설정할 수 있습니다.

 

동작 방식

  1. 스크롤바 필요 여부 판단:
    스크롤바는 리스트의 총 아이템 개수가 마지막 보이는 아이템보다 많을 때에만 그려집니다.
    즉, 스크롤이 필요한 경우에만 스크롤바가 나타납니다.

  2. 스크롤바 위치 계산:
    • 스크롤바에서 각 아이템의 높이는 전체 리스트 아이템 수에 따라 나누어 계산됩니다.
    • 첫 번째로 보이는 아이템의 인덱스를 기준으로 스크롤바의 Y축 오프셋이 계산됩니다.
  3. 스크롤바 그리기:
    계산된 높이와 너비로 오른쪽 끝에 맞춰 둥근 직사각형 형태의 스크롤바가 그려집니다.

 

사용 예시

다음과 같이 LazyColumn에 drawScrollbar 함수를 적용할 수 있습니다.

val listState = rememberLazyListState()

LazyColumn(
    modifier = Modifier
        .fillMaxSize()
        .drawScrollbar(state = listState),
    state = listState
) {
    items(100) { index ->
        Text("Item $index", Modifier.padding(16.dp))
    }
}

위 예시에서는 100개의 아이템이 포함된 LazyColumn에 커스텀 스크롤바가 추가됩니다.
스크롤바의 색상, 너비, 하단 패딩 등을 필요에 맞게 변경할 수 있습니다.

 

 

아쉬운 점

스크롤할 때 스크롤바가 자연스럽지 않게 그려지는 문제가 있습니다.

짧아졌다 길어졌다하는 문제가 있습니다.

 

추후 더 자연스럽게 그려지도록 개선하여 추가로 작성할 예정입니다.

반응형

'Android > Compose' 카테고리의 다른 글

[Compose] SMS Retriever API - SMS 인증번호 자동입력  (0) 2024.10.01
[Compose] SnackBar Duration Custom  (0) 2024.10.01
[Compose] Modifier Extension - AddFocusCleaner  (0) 2024.09.25
[Compose] LazyColumn Drag And Drop Reordering  (0) 2024.09.09
[Compose] Jetpack Compose 상태 관리 기초  (0) 2024.09.08
'Android/Compose' 카테고리의 다른 글
  • [Compose] SMS Retriever API - SMS 인증번호 자동입력
  • [Compose] SnackBar Duration Custom
  • [Compose] Modifier Extension - AddFocusCleaner
  • [Compose] LazyColumn Drag And Drop Reordering
Moondev
Moondev
공부 기록장
  • Moondev
    Moondev
    Moondev
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Android
        • ViewSystem
        • Compose
      • Language
        • Kotlin
      • Review
        • 프로젝트 후기
        • Conference 후기
        • 우아한테크코스 후기
      • Etc
        • Git
        • Gradle
  • 링크

    • GitHub
  • 인기 글

  • 300x250
  • hELLO· Designed By정상우.v4.10.3
Moondev
[Compose] Modifier Extension - DrawScrollbar
상단으로

티스토리툴바