ControlledComposition
Function
Common
@TestOnly
public fun ControlledComposition(
applier: Applier<*>,
parent: CompositionContext,
): ControlledComposition
This method is a way to initiate a composition. Optionally, a parent
CompositionContext
can
be provided to make the composition behave as a sub-composition of the parent or a Recomposer
can be provided.
A controlled composition allows direct control of the composition instead of it being controlled
by the Recomposer
passed ot the root composition.
It is important to call Composition.dispose
this composer is no longer needed in order to
release resources.
Parameters
applier | The Applier instance to be used in the composition. |
parent | The parent CompositionContext . |
Common
@TestOnly
@ExperimentalComposeApi
public fun ControlledComposition(
applier: Applier<*>,
parent: CompositionContext,
recomposeCoroutineContext: CoroutineContext,
): ControlledComposition
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++ }
}
}
}
}