ShimmerScope class final

Puts every Shimmer below it on one clock and one band.

A bare Shimmer owns its own AnimationController and sweeps the gradient across its own box. Put three of them on a screen and you get three clocks, each started when its widget mounted, each running a full highlight across a box the size of an avatar or a line of text. Wrapping them changes both halves of that: the scope holds the only controller, and each Shimmer resolves its own position inside the scope's box and paints the slice of the sweep that lands on it. One band crosses the screen.

ShimmerScope(
  child: Column(
    children: [
      for (final row in rows)
        Shimmer.fromColors(
          baseColor: Colors.grey.shade300,
          highlightColor: Colors.grey.shade100,
          child: row,
        ),
    ],
  ),
)

The scope owns period and loop, because those describe the clock. Everything else stays on the individual Shimmer: its colors, its Shimmer.direction, its Shimmer.enabled flag, its Shimmer.semanticsLabel. A widget with enabled: false holds still on whatever part of the band it was showing while its neighbours carry on.

The sweep is anchored to the scope's box rather than to the widgets inside it. A Shimmer scrolling through a list therefore moves through the band instead of carrying its own copy along, except while the band is held still by enabled: false or by reduced motion, when nothing repaints it. Reduced motion otherwise works as it does without a scope: MediaQuery.disableAnimationsOf freezes the clock.

Adding a scope is the only thing that changes any of this. A Shimmer with no scope above it runs exactly as it did before scopes existed.

Inheritance

Constructors

ShimmerScope({Key? key, required Widget child, Duration period = const Duration(milliseconds: 1500), int loop = 0, bool enabled = true})
Creates a scope that drives every Shimmer in child.
const

Properties

child Widget
The subtree whose shimmers share this scope's clock and band. The scope takes the size of this child, and that size is the distance the sweep travels.
final
enabled bool
When false, the shared clock pauses in place and every Shimmer below holds the band where it is.
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
loop int
Number of sweeps before the clock stops. 0 (the default) repeats forever.
final
period Duration
Duration of one sweep across the whole scope. Defaults to 1500 ms.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<ShimmerScope>
Creates the mutable state for this widget at a given location in the tree.
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.
override
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