abstract class Node : DelegatableNode
The longer-lived object that is created for each Modifier.Element applied to a androidx.compose.ui.layout.Layout. Most Modifier.Node implementations will have a corresponding "Modifier Factory" extension method on Modifier that will allow them to be used indirectly, without ever implementing a Modifier.Node subclass directly. In some cases it may be useful to define a custom Modifier.Node subclass in order to efficiently implement some collection of behaviors that requires maintaining state over time and over many recompositions where the various provided Modifier factories are not sufficient.
When a Modifier is set on a androidx.compose.ui.layout.Layout, each Modifier.Element contained in that linked list will result in a corresponding Modifier.Node instance in a matching linked list of Modifier.Nodes that the androidx.compose.ui.layout.Layout will hold on to. As subsequent Modifier chains get set on the androidx.compose.ui.layout.Layout, the linked list of Modifier.Nodes will be diffed and updated as appropriate, even though the Modifier instance might be completely new. As a result, the lifetime of a Modifier.Node is the intersection of the lifetime of the androidx.compose.ui.layout.Layout that it lives on and a corresponding Modifier.Element being present in the androidx.compose.ui.layout.Layout's Modifier.
If one creates a subclass of Modifier.Node, it is expected that it will implement one or more interfaces that interact with the various Compose UI subsystems. To use the Modifier.Node subclass, it is expected that it will be instantiated by adding a androidx.compose.ui.node.ModifierNodeElement to a Modifier chain.
Properties
val coroutineScope: CoroutineScope
A CoroutineScope that can be used to launch tasks that should run while the node is attached.
The scope is accessible between onAttach and onDetach calls, and will be cancelled after the node is detached (after onDetach returns).
var isAttached: Boolean
Indicates that the node is attached to a androidx.compose.ui.layout.Layout which is part of the UI tree. This will get set to true right before onAttach is called, and set to false right after onDetach is called.
open val shouldAutoInvalidate: Boolean
If this property returns true, then nodes will be automatically invalidated after the modifier update completes (For example, if the returned Node is a DrawModifierNode, its androidx.compose.ui.node.invalidateDraw function will be invoked automatically as part of auto invalidation).
This is enabled by default, and provides a convenient mechanism to schedule invalidation and apply changes made to the modifier. You may choose to set this to false if your modifier has auto-invalidatable properties that do not frequently require invalidation to improve performance by skipping unnecessary invalidation. If autoInvalidate is set to false, you must call the appropriate invalidate functions manually when the modifier is updated or else the updates may not be reflected in the UI appropriately.
Functions
onAttach
open fun onAttach()
Called when the node is attached to a androidx.compose.ui.layout.Layout which is part of the UI tree. When called, node is guaranteed to be non-null. You can call sideEffect, coroutineScope, etc. This is not guaranteed to get called at a time where the rest of the Modifier.Nodes in the hierarchy are "up to date". For instance, at the time of calling onAttach for this node, another node may be in the tree that will be detached by the time Compose has finished applying changes. As a result, if you need to guarantee that the state of the tree is "final" for this round of changes, you should use the sideEffect API to schedule the calculation to be done at that time.
onDetach
open fun onDetach()
Called when the node is not attached to a androidx.compose.ui.layout.Layout which is not a part of the UI tree anymore. Note that the node can be reattached again.
This should be called right before the node gets removed from the list, so you should still be able to traverse inside of this method. Ideally we would not allow you to trigger side effects here.
onReset
open fun onReset()
Called when the node is about to be moved to a pool of layouts ready to be reused. For example it happens when the node is part of the item of LazyColumn after this item is scrolled out of the viewport. This means this node could be in future reused for a androidx.compose.ui.layout.Layout displaying a semantically different content when the list will be populating a new item.
Use this callback to reset some local item specific state, like "is my component focused".
This callback is called while the node is attached. Right after this callback the node will be detached and later reattached when reused.
sideEffect
fun sideEffect(effect: () -> Unit)
This can be called to register effect as a function to be executed after all of the changes to the tree are applied.
This API can only be called if the node isAttached.