Composition

Function

Common
public fun Composition(applier: Applier<*>, parent: CompositionContext): Composition

This method is the way to initiate a composition. parent CompositionContext can be

  • provided to make the composition behave as a sub-composition of the parent. If composition does
  • not have a parent, Recomposer instance should be provided.

It is important to call Composition.dispose when composition is no longer needed in order to release resources.

Parameters

applierThe Applier instance to be used in the composition.
parentThe parent CompositionContext.
Common
@ExperimentalComposeApi
public fun Composition(
    applier: Applier<*>,
    parent: CompositionContext,
    recomposeCoroutineContext: CoroutineContext,
): Composition

Create a Composition using applier to manage the composition, as a child of parent.

When used in a configuration that supports concurrent recomposition, hint to the environment that recomposeCoroutineContext should be used to perform recomposition. Recompositions will be launched into the

Code Examples

CustomTreeComposition

@Suppress("unused")
fun CustomTreeComposition() {
    // Provided we have a tree with a node base type like the following
    abstract class Node {
        val children = mutableListOf<Node>()
    }
    // We would implement an Applier class like the following, which would teach compose how to
    // manage a tree of Nodes.
    class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
        override fun insertTopDown(index: Int, instance: Node) {
            current.children.add(index, instance)
        }
        override fun insertBottomUp(index: Int, instance: Node) {
            // Ignored as the tree is built top-down.
        }
        override fun remove(index: Int, count: Int) {
            current.children.remove(index, count)
        }
        override fun move(from: Int, to: Int, count: Int) {
            current.children.move(from, to, count)
        }
        override fun onClear() {
            root.children.clear()
        }
    }
    // A function like the following could be created to create a composition provided a root Node.
    fun Node.setContent(parent: CompositionContext, content: @Composable () -> Unit): Composition {
        return Composition(NodeApplier(this), parent).apply { setContent(content) }
    }
    // assuming we have Node sub-classes like "TextNode" and "GroupNode"
    class TextNode : Node() {
        var text: String = ""
        var onClick: () -> Unit = {}
    }
    class GroupNode : Node()
    // Composable equivalents could be created
    @Composable
    fun Text(text: String, onClick: () -> Unit = {}) {
        ComposeNode<TextNode, NodeApplier>(::TextNode) {
            set(text) { this.text = it }
            set(onClick) { this.onClick = it }
        }
    }
    @Composable
    fun Group(content: @Composable () -> Unit) {
        ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
    }
    // and then a sample tree could be composed:
    fun runApp(root: GroupNode, parent: CompositionContext) {
        root.setContent(parent) {
            var count by remember { mutableStateOf(0) }
            Group {
                Text("Count: $count")
                Text("Increment") { count++ }
            }
        }
    }
}