Skip to content

nanihadesuka/LazyColumnScrollbar

Folders and files

NameName
Last commit message
Last commit date
Apr 21, 2024
Nov 14, 2024
Sep 15, 2024
Sep 15, 2024
Nov 14, 2024
Sep 15, 2024
Aug 26, 2021
Jun 30, 2024
Sep 15, 2024
Sep 15, 2024
Aug 26, 2021
Aug 26, 2021
Jul 15, 2023
Mar 18, 2023
Apr 13, 2024

Repository files navigation

License Foo23 - Bar Foo23 - Bar

Scrollbars implementation for jetpack compose

Compose implementation of the scroll bar. Can drag, scroll smoothly and includes animations.

Features:

  • Support for:
    • Column, Row, LazyColumn, LazyRow, LazyVerticalGrid, LazyHorizontalGrid
  • Takes into account:
    • sticky headers
    • reverseLayout
  • Optional current position indicator
  • Multiple selection modes:
    • States (Disabled, Full, Thumb)
    • Actionable states (Always, WhenVisible)
  • Customizable look
  • Easy integration with other composables
  • Extensive UI tests
  • Sample app

Installation

Add it in your root build.gradle at the end of repositories:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Add it to your app build.gradle

dependencies {
    implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0'
}

Available scrolls components

  • ColumnScrollbar
  • RowScrollbar
  • LazyColumnScrollbar
  • LazyRowScrollbar
  • LazyVerticalGridScrollbar
  • LazyHorizontalGridScrollbar

Example for LazyColumn

val listData = (0..1000).toList()
val listState = rememberLazyListState()

LazyColumnScrollbar(
  state = listState,
  settings = ScrollbarSettings.Default  
) {
    LazyColumn(state = listState) {
        items(listData) {
            Text("Item $it")
        }
    }
}

indicatorContent example:

indicatorContent = { index, isThumbSelected ->
    Text(
        text = "i: $index",
        Modifier.background(if (isThumbSelected) Color.Red else Color.Black, CircleShape)
    )
}

Default settings parameters

/**
 * @param thumbMinLength Thumb minimum length proportional to total scrollbar's length (eg: 0.1 -> 10% of total)
 */
@Stable
data class ScrollbarSettings(
  val enabled: Boolean = Default.enabled,
  val side: ScrollbarLayoutSide = Default.side,
  val alwaysShowScrollbar: Boolean = Default.alwaysShowScrollbar,
  val scrollbarPadding: Dp = Default.scrollbarPadding,
  val thumbThickness: Dp = Default.thumbThickness,
  val thumbShape: Shape = Default.thumbShape,
  val thumbMinLength: Float = Default.thumbMinLength,
  val thumbMaxLength: Float = Default.thumbMaxLength,
  val thumbUnselectedColor: Color = Default.thumbUnselectedColor,
  val thumbSelectedColor: Color = Default.thumbSelectedColor,
  val selectionMode: ScrollbarSelectionMode = Default.selectionMode,
  val selectionActionable: ScrollbarSelectionActionable = Default.selectionActionable,
  val hideDelayMillis: Int = Default.hideDelayMillis,
  val hideDisplacement: Dp = Default.hideDisplacement,
  val hideEasingAnimation: Easing = Default.hideEasingAnimation,
  val durationAnimationMillis: Int = Default.durationAnimationMillis,
) {
  init {
    require(thumbMinLength <= thumbMaxLength) {
      "thumbMinLength ($thumbMinLength) must be less or equal to thumbMaxLength ($thumbMaxLength)"
    }
  }

  companion object {
    val Default = ScrollbarSettings(
      enabled = true,
      side = ScrollbarLayoutSide.End,
      alwaysShowScrollbar = false,
      thumbThickness = 6.dp,
      scrollbarPadding = 8.dp,
      thumbMinLength = 0.1f,
      thumbMaxLength = 1.0f,
      thumbUnselectedColor = Color(0xFF2A59B6),
      thumbSelectedColor = Color(0xFF5281CA),
      thumbShape = CircleShape,
      selectionMode = ScrollbarSelectionMode.Thumb,
      selectionActionable = ScrollbarSelectionActionable.Always,
      hideDelayMillis = 400,
      hideDisplacement = 14.dp,
      hideEasingAnimation = FastOutSlowInEasing,
      durationAnimationMillis = 500,
    )
  }
}

License

Copyright © 2024, nani, Released under MIT License