BloomVsyncWidget class abstract

A reactive widget that dynamically and explicitly tracks Bloom dependencies while providing an element-managed Flutter TickerProvider for driving animations and tickers without boilerplate.

Seamlessly pairs BloomWidget's reactive capabilities with element-level TickerProvider lifecycle management, ensuring all tickers created via vsync are synchronized with TickerMode and safely disposed upon unmount.

System Architectural Flow

[ Upstream Bloom<T> Mutation ]
       │
       │ (Phase 1: 0-Compute Push-Dirty Invalidation)
       ▼
[ RawComputedTerminal<Widget>.onInvalidated: markNeedsBuild() ]
       │
       │ (Flutter Engine Frame Pipeline Scheduling)
       ▼
[ BloomVsyncElement.rebuild() -> performRebuild() ]
       │
       │ (Phase 2: Lazy-Pull Evaluation via terminal.data)
       ▼
┌────────────────────────────────────────────────────────────────────────┐
│ If Clean: Returns cached Widget in O(1) (0-Compute)                    │
│ If Dirty: Evaluates BloomVsyncWidget.build(context, via, vsync)         │
└────────────────────────────────────────────────────────────────────────┘

Key Invariants & Architectural Benefits

  1. Zero Stateful Ticker Boilerplate: Eliminates the need for StatefulWidget and SingleTickerProviderStateMixin.
  2. Immutable Const Contract: Supports const constructors with zero mutable state on the widget instance.
  3. Element-Owned Ticker Lifecycle: The underlying BloomVsyncElement provides TickerProvider directly, preventing re-binding hazards and memory leaks across rebuilds.
  4. Automatic Ticker Muting: Integrates with Flutter's TickerMode, pausing tickers automatically when routes or tabs are hidden or inactive.
  5. 0-Compute Reactive Memoization: Inherits RawComputedTerminal caching to skip build re-evaluation when dependencies resolve to clean.

Warning (Anti-Pattern Prevention):

  • Do NOT create raw AnimationController instances inside build directly, as rebuilding creates new controllers and leaks resources. Use external durable controllers or initialize persistent resources in a ViewModel.

BAD:

// [Anti-Pattern] Re-allocating controller resource inside build()
Widget build(BuildContext context, BloomVia via, TickerProvider vsync) {
  final ctrl = AnimationController(vsync: vsync, duration: const Duration(milliseconds: 300)); // Leak!
  return FadeTransition(opacity: ctrl, child: const Text('Hello'));
}

GOOD:

// [Recommended] Pass vsync to external components or use composed.animate
class TabbedHeaderWidget extends BloomVsyncWidget {
  const TabbedHeaderWidget({required this.tabIndexBloom, super.key});
  final Bloom<int> tabIndexBloom;

  @override
  Widget build(BuildContext context, BloomVia via, TickerProvider vsync) {
    final tabIndex = via(tabIndexBloom);
    return DefaultTabController(
      length: 3,
      initialIndex: tabIndex,
      child: const TabBar(tabs: [Tab(text: 'A'), Tab(text: 'B'), Tab(text: 'C')]),
    );
  }
}

Examples

class CustomTickerWidget extends BloomVsyncWidget {
  const CustomTickerWidget({required this.activeBloom, super.key});
  final Bloom<bool> activeBloom;

  @override
  Widget build(BuildContext context, BloomVia via, TickerProvider vsync) {
    final isActive = via(activeBloom);
    return Text('Active: $isActive, Vsync: $vsync');
  }
}
Inheritance

Constructors

BloomVsyncWidget({Key? key})
Initializes a BloomVsyncWidget with an optional key.
const

Properties

hashCode → int
The hash code for this object.
no setterinherited
key → Key?
Controls how one widget replaces another widget in the tree.
finalinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

build(BuildContext context, BloomVia via, TickerProvider vsync) → Widget
Describes the part of the user interface represented by this widget, with explicit BloomVia tracking and an injected TickerProvider.
createElement() → BloomVsyncElement
Inflates this configuration to a concrete instance.
override
debugDescribeChildren() → List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String
Returns a one-line detailed description of the object.
inherited
toStringShort() → String
A short, textual description of this widget.
inherited

Operators

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