AbstractApplier
Class
Common
public abstract class AbstractApplier<T>(public val root: T) : Applier<T>
An abstract Applier
implementation.
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++ }
}
}
}
}