Stylianos Gakis
11/10/2024, 8:25 PMStylianos Gakis
11/10/2024, 8:25 PMprivate data class OverlaidIndicationConnectionElement(
val overlaidIndicationState: OverlaidIndicationState,
val interactionSource: MutableInteractionSource,
) : ModifierNodeElement<OverlaidIndicationConnectionNode>() {
override fun create(): OverlaidIndicationConnectionNode {
return OverlaidIndicationConnectionNode(overlaidIndicationState, interactionSource)
}
override fun update(node: OverlaidIndicationConnectionNode) {
node.overlaidIndicationState = overlaidIndicationState
node.interactionSource = interactionSource
}
}
private class OverlaidIndicationConnectionNode(
var overlaidIndicationState: OverlaidIndicationState,
var interactionSource: MutableInteractionSource,
) : LayoutAwareModifierNode, Modifier.Node() {
private var offset = IntOffset(0, 0)
override fun onAttach() {
coroutineScope.launch {
interactionSource.interactions.collect {
overlaidIndicationState.offset = offset
overlaidIndicationState.interactionSource.tryEmit(it)
}
}
}
override fun onPlaced(coordinates: LayoutCoordinates) {
offset = coordinates.positionInParent().round()
}
}
But the problem here is that I am doing interactionSource.interactions.collect
on onAttatch
, but that won't be re-run if the interaction source were to ever change.Stylianos Gakis
11/10/2024, 8:25 PMupdate
function on my node by making the vars private, and in there I will have to do some bookkeeping regarding cancelling the old collection and starting a new one, all by manually working on a Job
object.
private data class OverlaidIndicationConnectionElement(
val overlaidIndicationState: OverlaidIndicationState,
val interactionSource: MutableInteractionSource,
) : ModifierNodeElement<OverlaidIndicationConnectionNode>() {
override fun create(): OverlaidIndicationConnectionNode {
return OverlaidIndicationConnectionNode(overlaidIndicationState, interactionSource)
}
override fun update(node: OverlaidIndicationConnectionNode) {
node.update(overlaidIndicationState, interactionSource)
}
}
private class OverlaidIndicationConnectionNode(
private var overlaidIndicationState: OverlaidIndicationState,
private var interactionSource: MutableInteractionSource,
) : LayoutAwareModifierNode, Modifier.Node() {
private var offset = IntOffset(0, 0)
private var collectingJob: Job? = null
override fun onAttach() {
startCollection()
}
fun update(overlaidIndicationState: OverlaidIndicationState, interactionSource: MutableInteractionSource) {
this.overlaidIndicationState = overlaidIndicationState
this.interactionSource = interactionSource
startCollection()
}
private fun startCollection() {
collectingJob?.cancel()
collectingJob = coroutineScope.launch {
interactionSource.interactions.collect {
overlaidIndicationState.offset = offset
overlaidIndicationState.interactionSource.tryEmit(it)
}
}
}
override fun onPlaced(coordinates: LayoutCoordinates) {
offset = coordinates.positionInParent().round()
}
}
I haven't found enough such nodes online to try to compare my solution against, most are doing their own thing and I haven't found one which needs to do such a coroutine collection etc.
If anyone sees anything wrong with my implementation or has some other input on this I would appreciate it!Stylianos Gakis
11/10/2024, 8:27 PM@Stable
internal interface OverlaidIndicationState {
var offset: IntOffset
val interactionSource: MutableInteractionSource
}
private class OverlaidIndicationStateImpl() : OverlaidIndicationState {
override var offset by mutableStateOf(IntOffset(0, 0))
override val interactionSource: MutableInteractionSource = MutableInteractionSource()
}
The details of this are not important here I think, I just thought I'd put it here since it might be confusing without it otherwise.efemoney
11/11/2024, 5:21 PMStylianos Gakis
11/11/2024, 5:39 PM