SectionedListController<K extends Object, Section, Item> class

Controller for a SectionedSliverList.

Owns the imperative API (addItem, moveItem, setItems, expandSection, ...). When supplied to a SectionedSliverList constructed via the .controlled named constructor, the widget binds to it and renders whatever state the controller currently holds. The widget never reads section/item data from props in that mode — the controller IS the source of truth.

In default / .fromMap mode the widget creates and disposes its own internal controller; the user never sees one.

Lifetime: external controllers must be disposed by their owner. Internally-created controllers are disposed by the widget.

A controller is designed to drive exactly one mounted widget at a time. Mounting two widgets against the same controller asserts in debug.

SectionedListController implements Listenable: addListener / removeListener forward to the underlying TreeController and fire on structural changes only (insert / remove / move / reorder / expand / collapse). Payload-only mutations (updateSection, updateItem) do NOT fire the structural channel — subscribe via addSectionPayloadListener / addItemPayloadListener instead.

Inside runBatch, structural notifications coalesce to a single fire at batch exit, and payload notifications are deferred and deduped by key.

Implemented types

Constructors

SectionedListController({required TickerProvider vsync, required K sectionKeyOf(Section section), required K itemKeyOf(Item item), Duration animationDuration = const Duration(milliseconds: 300), Curve animationCurve = Curves.easeInOut, double itemIndent = 0.0, bool preserveExpansion = true})

Properties

allSectionKeys List<K>
All section keys in render order, INCLUDING pending-deletion.
no setter
allSections List<Section>
All section payloads in render order, INCLUDING those currently mid-exit-animation. Escape hatch for callers that need to introspect mid-animation state.
no setter
animationCurve Curve
getter/setter pair
animationDuration Duration
getter/setter pair
hashCode int
The hash code for this object.
no setterinherited
itemIndent double
Visual indent applied to items under section headers, in logical pixels. Forwards to TreeController.indentWidth.
getter/setter pair
itemKeyOf → K Function(Item item)
Extracts the item's stable key from its payload. Same role as sectionKeyOf.
final
preserveExpansion bool
getter/setter pair
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
sectionKeyOf → K Function(Section section)
Extracts the section's stable key from its payload. Captured at construction so all controller-side methods can convert user-supplied Section values into keys without callers having to pass the key explicitly.
final
sectionKeys List<K>
Section keys in render order, EXCLUDING pending-deletion.
no setter
sections List<Section>
Section payloads in render order, EXCLUDING sections currently mid-exit-animation. This is the input shape reorderSections implicitly expects (via the keys returned by sectionKeys).
no setter
treeController TreeController<SecKey<K>, SecPayload<Section, Item>>
Underlying tree controller. Exposed for the widget's render layer (it must construct a SliverTree against this). Not part of the supported public API for end users — calling structural methods directly on the underlying tree bypasses the section/item type invariants this controller enforces.
no setter

Methods

addItem(Item item, {required K toSection, int? index, bool animate = true}) → void
Inserts item under toSection at index (or at the end).
addItemPayloadListener(void listener(K itemKey)) → void
Subscribes to item-payload changes. Fires after every successful updateItem call with the affected key. Inside runBatch, multiple updateItem(k, ...) calls for the same k produce a single callback at batch exit.
addListener(VoidCallback listener) → void
Subscribes to structural changes. Fires once per mutation (insert / remove / move / reorder / expand / collapse), or once per outermost runBatch regardless of how many structural mutations the body contained.
override
addSection(Section section, {int? index, Iterable<Item>? items, bool animate = true}) → void
Inserts section at index (or at the end when null). If items is non-empty they become the section's children — this initial child population is structural and does not animate per item; the section's own appearance respects animate.
addSectionPayloadListener(void listener(K sectionKey)) → void
Subscribes to section-payload changes. Fires after every successful updateSection call with the affected key. Inside runBatch, multiple updateSection(k, ...) calls for the same k produce a single callback at batch exit.
allItemKeysOf(K sectionKey) List<K>
All item keys under sectionKey in render order, INCLUDING pending-deletion.
allItemsOf(K sectionKey) List<Item>
All item payloads under sectionKey in render order, INCLUDING pending-deletion.
collapseAll({bool animate = true}) → void
collapseSection(K sectionKey, {bool animate = true}) → void
debugBindWidget() → void
Marks this controller as bound to a widget. Asserts that no other widget is currently bound. Called by SectionedSliverListState during initState and after a controller swap.
debugSnapshotCurrentChildren() Map<K, List<K>>
Snapshots used by the widget's initial-expansion logic (mirrors the existing public hooks on TreeSyncController).
debugSnapshotRememberedSectionKeys() Set<K>
debugUnbindWidget() → void
Releases the binding established by debugBindWidget. Called by SectionedSliverListState during dispose and before a controller swap.
dispose() → void
expandAll({bool animate = true}) → void
expandSection(K sectionKey, {bool animate = true}) → void
getItem(K itemKey) → Item?
getSection(K sectionKey) → Section?
hasItem(K itemKey) bool
hasSection(K sectionKey) bool
indexOfItem(K itemKey) int
Position of itemKey among its section's children in live-list space (skipping pending-deletion siblings). Returns -1 when itemKey is not present, is itself pending-deletion, or is not an item.
isExpanded(K sectionKey) bool
itemCount(K sectionKey) int
Number of items currently belonging to sectionKey, regardless of expansion state. Returns 0 for unknown sections. Includes pending-deletion children — this is the count rendered by the header, since exit animations are still visible.
itemKeysOf(K sectionKey) List<K>
Item keys under sectionKey in render order, EXCLUDING pending-deletion.
itemsOf(K sectionKey) List<Item>
Item payloads under sectionKey in render order, EXCLUDING pending-deletion. Returns [] for unknown sections.
moveItem(K itemKey, {required K toSection, int? index}) → void
Reparents itemKey under toSection. When index is null, the item is appended to toSection's children.
moveItemInSection(K itemKey, int toIndex) → void
moveSection(K sectionKey, int toIndex) → void
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
removeItem(K itemKey, {bool animate = true}) → void
removeItemPayloadListener(void listener(K itemKey)) → void
removeListener(VoidCallback listener) → void
Remove a previously registered closure from the list of closures that the object notifies.
override
removeSection(K sectionKey, {bool animate = true}) → void
removeSectionPayloadListener(void listener(K sectionKey)) → void
reorderItems(K sectionKey, List<K> orderedKeys) → void
reorderSections(List<K> orderedKeys) → void
runBatch<T>(T body()) → T
Coalesces structural notifications across the mutations performed inside body into a single post-batch refresh. Payload notifications are also coalesced and deduped by key. Delegates to the underlying TreeController.runBatch.
sectionOf(K itemKey) → K?
setItems(K sectionKey, Iterable<Item> items, {bool animate = true}) → void
Replaces all items under sectionKey. Diffs against current children and animates inserts/removes.
setSections(Iterable<Section> sections, {required Iterable<Item> itemsOf(Section section), bool animate = true}) → void
Replaces all sections. Diffs against current state and animates inserts, removes, and reparenting.
toggleSection(K sectionKey, {bool animate = true}) → void
toString() String
A string representation of this object.
inherited
updateItem(K itemKey, Item item) → void
Updates itemKey's payload to item. Asserts that itemKey already exists. See updateSection for why the key is explicit.
updateSection(K sectionKey, Section section) → void
Updates sectionKey's payload to section without touching the section's items. Asserts that sectionKey already exists.

Operators

operator ==(Object other) bool
The equality operator.
inherited