Android 12 Developer Preview is here! Try it out, and give us your feedback!

AbstractApplier

abstract class AbstractApplier<T> : Applier<T>
kotlin.Any
   ↳ androidx.compose.runtime.AbstractApplier

An abstract Applier implementation.

import androidx.compose.runtime.Composition
import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// 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++ }
        }
    }
}

Summary

Public constructors
<init>(root: T)

An abstract Applier implementation.

Public methods
Unit

Move to the root and remove all nodes from the root, preparing both this Applier and its root to be used as the target of a new composition in the future.

open Unit
down(node: T)

Indicates that the applier is getting traversed "down" the tree.

open Unit
up()

Indicates that the applier is getting traversed "up" the tree.

Protected methods
Unit
MutableList<T>.move(from: Int, to: Int, count: Int)

abstract Unit

Called to perform clearing of the root when clear is called.

Unit
MutableList<T>.remove(index: Int, count: Int)

Inherited functions