shimmer_animation_kit
A Flutter package providing shimmer loading animations with auto shape detection, synchronized animation scope, manual widgets, theming, and full accessibility support.
Features
- Auto shape detection — wrap any widget tree;
ShimmerKitanalyses it and builds a matching skeleton automatically ShimmerScopesync — oneAnimationControllerdrives every shimmer on screen, zero jank- Manual widgets —
ShimmerBox,ShimmerCircleWidget,ShimmerTextWidget,ShimmerListfor hand-crafted layouts - Full theming —
ShimmerTheme(ThemeExtension) with light/dark defaults and per-widget overrides - 5 directions —
leftToRight,rightToLeft,topToBottom,bottomToTop,diagonal - Accessibility — respects
MediaQuery.disableAnimations, exposesSemantics(label: 'Loading') - Zero dependencies — pure Flutter, no third-party packages
Installation
dependencies:
shimmer_animation_kit: ^0.1.0
Quick Start
import 'package:shimmer_animation_kit/shimmer_animation_kit.dart';
// 1. Wrap your screen (or subtree) with ShimmerScope.
// 2. Set isLoading: true while fetching data.
ShimmerScope(
child: Column(
children: [
ShimmerKit(
isLoading: _isLoading,
child: ProfileCard(), // real widget shown when loaded
),
ShimmerKit(
isLoading: _isLoading,
child: ArticleList(),
),
],
),
)
Both shimmers share a single animation controller — they pulse in perfect sync.
Auto-Detect vs Manual
| Use case | Approach |
|---|---|
| Unknown / complex layout | ShimmerKit(isLoading: true, child: ...) |
| Precise hand-crafted layout | ShimmerBox / ShimmerCircleWidget / ShimmerTextWidget |
Auto-detect (ShimmerKit)
ShimmerKit(
isLoading: true,
child: Row(
children: [
CircleAvatar(radius: 24),
Column(children: [Text('Name'), Text('Bio')]),
],
),
)
Manual
ShimmerScope(
child: Row(
children: [
ShimmerCircleWidget(diameter: 48),
const SizedBox(width: 12),
ShimmerTextWidget(lines: 2, width: 140),
],
),
)
API Reference
| Widget / Class | Key Parameters | Description |
|---|---|---|
ShimmerScope |
duration, child |
Provides shared AnimationController to descendants |
ShimmerKit |
isLoading, child, baseColor, highlightColor, direction |
Auto-detects child shapes and renders shimmer skeleton |
ShimmerBox |
width, height, borderRadius |
Animated rectangle |
ShimmerCircleWidget |
diameter |
Animated circle |
ShimmerTextWidget |
lines, lineHeight, lineSpacing, lastLineWidthFraction, width |
Stacked text-line bars |
ShimmerList |
itemCount, itemBuilder |
Repeating shimmer rows |
ShimmerTheme |
baseColor, highlightColor, duration, direction |
ThemeExtension for app-wide defaults |
ShimmerDirection |
— | Enum: leftToRight, rightToLeft, topToBottom, bottomToTop, diagonal |
ShimmerScope
ShimmerScope holds one AnimationController and shares its value down the tree via an InheritedWidget. All descendant shimmer widgets read this single value:
ShimmerScope
└─ AnimationController (repeats forever)
└─ _ShimmerScopeInherited (InheritedWidget)
├─ ShimmerBox ← reads value
├─ ShimmerCircleWidget ← reads value
└─ ShimmerKit ← reads value
Why one controller?
Multiple AnimationControllers would drift out of phase. A shared controller guarantees all shimmers are pixel-identical at every frame, with no extra rebuild cost.
Theming
Register ShimmerTheme in your ThemeData:
ThemeData(
extensions: [
ShimmerTheme(
baseColor: Color(0xFFE0E0E0),
highlightColor: Color(0xFFF5F5F5),
duration: Duration(milliseconds: 1200),
direction: ShimmerDirection.diagonal,
),
],
)
Dark mode — provide a theme extension in your dark ThemeData:
darkTheme: ThemeData.dark().copyWith(
extensions: [ShimmerTheme.dark],
),
If no ShimmerTheme extension is found, the package automatically selects ShimmerTheme.light or ShimmerTheme.dark based on Theme.of(context).brightness.
Accessibility
When the user enables Reduce Motion on their device, MediaQuery.disableAnimations becomes true. ShimmerScope detects this, stops the controller, and freezes the shimmer at a neutral mid-point value (0.5). The skeleton remains visible but stationary — no flicker, no movement.
Each active shimmer also exposes:
Semantics(label: 'Loading', excludeSemantics: true)
so screen readers announce the loading state without reading phantom widget text.
Contributing
- Fork the repo and create a feature branch.
- Run
flutter test— all tests must pass. - Run
flutter analyze— zero warnings. - Open a pull request with a clear description.
License
MIT © 2026 Seqato
Libraries
- shimmer_animation_kit
- A Flutter package providing shimmer loading animations with auto shape detection, synchronized animation scope, manual widgets, theming, and full accessibility support.