SparkBottomAppBarScrollBehavior

class SparkBottomAppBarScrollBehavior(val state: BottomAppBarState, val snapAnimationSpec: AnimationSpec<Float>?, val flingAnimationSpec: DecayAnimationSpec<Float>?, val canScroll: () -> Boolean = { true }) : BottomAppBarScrollBehavior

Scroll behavior for BottomAppBar that implements a pinned behavior similar to TopAppBar but with bottom-specific elevation logic. The bottom app bar stays pinned at the bottom and shows elevation when content has been scrolled up from a scrolled-down position (contentOffset 0), indicating there's content above the current scroll position.

Example usage with a scrollable screen:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ScrollableScreenWithBottomBar() {
// Create scroll behaviors for both bars if needed
val topBarBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val bottomBarBehavior = BottomAppBarSparkDefaults.bottomAppBarScrollBehavior()

Scaffold(
modifier = Modifier
.fillMaxSize()
// Connect both scroll behaviors
.nestedScroll(topBarBehavior.nestedScrollConnection)
.nestedScroll(bottomBarBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
title = { Text("My App") },
scrollBehavior = topBarBehavior
)
},
bottomBar = {
BottomAppBar(
scrollBehavior = bottomBarBehavior,
actions = {
ButtonOutlined(
onClick = { /* Handle click */},
text = "Cancel",
modifier = Modifier.weight(1f)
)
ButtonFilled(
onClick = { /* Handle click */},
text = "Save",
modifier = Modifier.weight(1f)
)
}
)
}
) { padding ->
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(padding),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(50) { index ->
ListItem(
headlineContent = { Text("Item ${index + 1}") }
)
}
}
}
}

This behavior uses the BottomAppBarState.contentOffset to determine elevation:

  • contentOffset 0: Content has been scrolled up from scrolled-down position, show elevation

  • contentOffset <= 0: At the top or scrolling down, no elevation needed

Additionally provides an overlappedFraction property (0.0 to 1.0+) that represents how much content has been scrolled above the bottom app bar, similar to TopAppBar's overlappedFraction but for bottom positioning.

Constructors

Link copied to clipboard
constructor(state: BottomAppBarState, snapAnimationSpec: AnimationSpec<Float>?, flingAnimationSpec: DecayAnimationSpec<Float>?, canScroll: () -> Boolean = { true })

Properties

Link copied to clipboard
val canScroll: () -> Boolean
Link copied to clipboard
Link copied to clipboard
open override val isPinned: Boolean = true
Link copied to clipboard
Link copied to clipboard

A value that represents the percentage of content that has been scrolled above the bottom app bar.

Link copied to clipboard
Link copied to clipboard
open override val state: BottomAppBarState