galex
03/24/2022, 10:23 AMonGloballyPositioned
inside Modifier.composed
?
That inside modifier doesn’t seem to be called!
fun Modifier.tooltip(
scope: CoroutineScope,
tooltipHostState: TooltipHostState,
text: String
) = composed {
var layoutCoordinates by remember { mutableStateOf<LayoutCoordinates?>(null) }
onGloballyPositioned {
layoutCoordinates = it
logger().d("tooltip", "onGloballyPositioned = $layoutCoordinates")
}
LaunchedEffect(layoutCoordinates) {
logger().d("tooltip", "LaunchedEffect = $layoutCoordinates")
scope.launch {
tooltipHostState.showTooltip(text)
}
}
return@composed this
}
What I am trying to do is to launch only once (LaunchedEffect) when onGloballyPositioned
is called 🤔Filip Wiesner
03/24/2022, 10:26 AMonGloballyPositioned
. Right now your tooltip
modifier takes the chain, doesn't add anything and returns it.efemoney
03/24/2022, 10:29 AMgalex
03/24/2022, 10:35 AMgalex
03/24/2022, 10:37 AMfun Modifier.tooltip(
tooltipHostState: HzTooltipHostState,
text: String
) = composed {
var layoutCoordinates by remember { mutableStateOf<LayoutCoordinates?>(null) }
LaunchedEffect(layoutCoordinates) {
logger().d("tooltip", "LaunchedEffect = $layoutCoordinates")
tooltipHostState.showTooltip(text)
}
return@composed this.then(onGloballyPositioned {
layoutCoordinates = it
logger().d("tooltip", "onGloballyPositioned = $layoutCoordinates")
})
}
It doesn’t seem the LaunchedEffect here runs only at every change of the LayoutCoordinates object as it’s the same ref all the time:
2022-03-24 12:35:12.950 30632-30632/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:35:12.957 30632-30632/app D/tooltip: LaunchedEffect = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:35:13.004 30632-30632/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:35:13.009 30632-30632/app D/tooltip: LaunchedEffect = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:35:13.274 30632-30632/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
efemoney
03/24/2022, 10:44 AMonGloballyPositioned { … }
should be fine (no need for this.then(...)
), Also you have two log statements so that would be twice the logs and finally, onGloballyPositioned callback is called many many times, it does not have any guarantees around being distinct and that should be the cause for most of the log statementsFilip Wiesner
03/24/2022, 10:44 AMreturn
and call this.then()
. Just let the modifier be the last statement that get's returned.
And for the recomposition, I am not sure why on first look. I would have to dig more but you shouldn't really care about recomposing too often. The problems start when it does not recompose and it should 😉Filip Wiesner
03/24/2022, 10:47 AMit does not have any guarantees around being distinct and that should be the cause for most of the log statementsYes but the state should change only when equality changes and
LaunchedEffect
has it as key. Maybe I am missing something obvious.efemoney
03/24/2022, 10:47 AMgalex
03/24/2022, 10:48 AMfun Modifier.tooltip(
tooltipHostState: HzTooltipHostState,
text: String
) = composed {
var layoutCoordinates by remember { mutableStateOf<LayoutCoordinates?>(null) }
if(layoutCoordinates != null) {
LaunchedEffect(layoutCoordinates) {
logger().d("tooltip", "LaunchedEffect = $layoutCoordinates")
tooltipHostState.showTooltip(text)
}
}
onGloballyPositioned {
layoutCoordinates = it
logger().d("tooltip", "onGloballyPositioned = $layoutCoordinates")
}
}
When null it was also being called, now the LaunchedEffect
is really called once per change of that object ref.
Thanks!Filip Wiesner
03/24/2022, 10:48 AMonGloballyPositioned
trigger we get a LaunchedEffect
trigger even though it looks like the same instanceFilip Wiesner
03/24/2022, 10:49 AMgalex
03/24/2022, 10:49 AMefemoney
03/24/2022, 10:49 AMgalex
03/24/2022, 10:50 AMFilip Wiesner
03/24/2022, 10:50 AMLayoutCoordinates
instance in the logs, my bad 🤦♂️galex
03/24/2022, 11:00 AMefemoney
03/24/2022, 11:01 AMgalex
03/24/2022, 11:02 AM2022-03-24 12:47:25.882 1245-1245/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:47:25.902 1245-1245/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:47:25.907 1245-1245/app D/tooltip: LaunchedEffect = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:47:25.945 1245-1245/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
2022-03-24 12:47:26.198 1245-1245/app D/tooltip: onGloballyPositioned = androidx.compose.ui.node.OnGloballyPositionedModifierWrapper@259780
efemoney
03/24/2022, 11:03 AMtooltip-oGP
and for the launched effect to be tooltip-lE
you would notice most of the logs are from oGP.galex
03/24/2022, 11:06 AMZach Klippenstein (he/him) [MOD]
03/24/2022, 3:08 PMcomposed
. You actually don't need this.then
. The receiver is already a Modifier
so you can just directly call modifier factory functions. But that receiver doesn't even matter so you can even return Modifier.foo()
. The returned modifier will always be chained anyway.Zach Klippenstein (he/him) [MOD]
03/24/2022, 3:11 PMZach Klippenstein (he/him) [MOD]
03/24/2022, 3:13 PMgalex
03/28/2022, 11:21 AM