Last active
August 1, 2023 20:19
-
-
Save ShikaSD/d6022a4f69ec7284852eb154876f07e5 to your computer and use it in GitHub Desktop.
onPlacedDemo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Preview | |
@Composable | |
private fun LazyColumnDemo() { | |
var spacerPositionOffset by remember { | |
mutableStateOf(Offset.Unspecified) | |
} | |
val configuration = LocalConfiguration.current | |
val windowSize = remember(configuration) { | |
DpSize(configuration.screenWidthDp.dp, configuration.screenHeightDp.dp) | |
} | |
Box(Modifier.fillMaxSize()) { | |
LazyColumn { | |
items(10) { | |
Box(Modifier.padding(4.dp)) { | |
Card { | |
Box( | |
Modifier | |
.background(Color.LightGray) | |
.fillMaxWidth() | |
.height(100.dp) | |
) | |
} | |
} | |
} | |
item { | |
Spacer(modifier = Modifier | |
.fillMaxWidth() | |
.height(40.dp) | |
.onPlaced { | |
spacerPositionOffset = it.positionInWindow() | |
} | |
) | |
val density = LocalDensity.current | |
DisposableEffect(density) { | |
// TODO: this is practically (un)placed | |
onDispose { | |
with(density) { | |
if (spacerPositionOffset != Offset.Unspecified | |
&& spacerPositionOffset.y < windowSize.height.roundToPx() / 2) { | |
spacerPositionOffset = Offset(0f, -40.dp.toPx()) | |
} else { | |
spacerPositionOffset = Offset.Unspecified | |
} | |
} | |
} | |
} | |
} | |
items(10) { | |
Box(Modifier.padding(4.dp)) { | |
Card { | |
Box( | |
Modifier | |
.background(Color.LightGray) | |
.fillMaxWidth() | |
.height(100.dp) | |
) | |
} | |
} | |
} | |
} | |
Button( | |
onClick = {}, modifier = Modifier | |
.align(Alignment.BottomCenter) | |
.height(40.dp) | |
.fillMaxWidth() | |
.layout { measurable, constraints -> | |
val placeable = measurable.measure(constraints) | |
layout(placeable.width, placeable.height) { | |
val position = coordinates?.positionInWindow() ?: Offset.Zero | |
val spacerPosition = | |
if (spacerPositionOffset == Offset.Unspecified) position else spacerPositionOffset | |
// windowSize is 25 pixels smaller on my emulator (no idea why), so offsetting it by 25 | |
val offset = if (spacerPosition.y > windowSize.height.roundToPx() + 25) { | |
IntOffset.Zero | |
} else { | |
IntOffset( | |
(spacerPosition.x - position.x).roundToInt(), | |
(spacerPosition.y - position.y).roundToInt() | |
) | |
} | |
placeable.place(offset) | |
} | |
} | |
) { | |
Text("Test") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment