Alexander Maryanovsky
/** * Draws a top-shadow, proportional (but capped) to the scrolled value. */ @Composable fun ScrollShadow( scrollState: ScrollState, modifier: Modifier ) { val elevation by remember(scrollState) { derivedStateOf { (scrollState.value/2).coerceAtMost(3).dp } } Box( modifier .height(1.dp) .offset(y = (-1).dp) .clip(OpenBottomShape) .shadow(elevation) ) } /** * A shape that clips the box such that only the shadow at the bottom is drawn. */ private val OpenBottomShape = GenericShape { size, _ -> moveTo(size.width, size.height) lineTo(size.width, Float.MAX_VALUE) lineTo(0f, Float.MAX_VALUE) lineTo(0f, size.height) } fun main() = singleWindowApplication { Column { Text("Header", Modifier.padding(24.dp), style = TextStyle(fontWeight = FontWeight.Bold)) Box(Modifier.fillMaxSize()) { val scrollState = rememberScrollState() ScrollShadow(scrollState, Modifier.fillMaxWidth()) Column(Modifier.verticalScroll(scrollState).fillMaxWidth()) { repeat(20) { Text("Item $it", Modifier.padding(16.dp)) } } VerticalScrollbar(rememberScrollbarAdapter(scrollState), Modifier.align(Alignment.CenterEnd)) } } }
Samson Jisso
A modern programming language that makes developers happier.