π¨ Adaptive Shimmer
The ultimate skeleton loader for Flutter. Zero dependencies, maximum power.
Why Choose This? β’ Get Started β’ Examples β’ Learn More
π Why Choose Adaptive Shimmer?
| Feature | Details |
|---|---|
| Zero Dependencies | Pure Flutter, no external packages |
| One Line of Code | Wrap any widget, get instant skeleton loading |
| Smart Auto-Detection | Automatically transforms your widgets to skeletons |
| 8 Directions | LTR, RTL, TTB, BTB, Diagonal, Wave, and more |
| Complete Control | Pause, resume, stop animations with ShimmerController |
| Beautiful Themes | 8 built-in presets + unlimited custom options |
| Accessibility First | Respects system motion preferences automatically |
| Advanced Features | Custom transformers, nested skeletons, memoization |
| Production Ready | Enterprise-grade Flutter apps |
π¦ Installation
flutter pub add adaptive_shimmer
Or add to pubspec.yaml:
dependencies:
adaptive_shimmer: ^1.2.0
β‘ Code Examples
1οΈβ£ Basic Loading (One Line!)
import 'package:adaptive_shimmer/adaptive_shimmer.dart';
AdaptiveShimmer(
loading: isLoading,
child: MyContentWidget(),
)
That's it! Shimmer applied, automatic on/off.
2οΈβ£ Auto-Transform with SmartSkeleton
No need for separate skeleton widgets!
SmartSkeleton(
loading: isLoading,
child: Column(
children: [
Text('Product Name'),
Image.network(productUrl),
Text('Price: $99.99'),
],
),
)
Automatically converts:
Text()β Skeleton linesImage()β Skeleton boxes- Respects shapes & borders
3οΈβ£ ListView/GridView Skeletons
Perfect for dynamic lists:
SmartCollectionSkeleton(
loading: isLoading,
type: CollectionType.list, // or .grid
skeletonConfig: CollectionSkeletonConfig(
itemCount: 5,
itemHeight: 120,
),
child: MyListView(),
)
4οΈβ£ Animation Control
final controller = ShimmerController();
AdaptiveShimmer(
loading: true,
controller: controller,
child: MyWidget(),
)
controller.pause(); // Pause
controller.resume(); // Resume
controller.stop(); // Stop
controller.toggle(); // Toggle
5οΈβ£ Themes (8 Built-in)
AdaptiveShimmer.withTheme(
loading: isLoading,
theme: ShimmerTheme.dark, // light, fast, slow, subtle, prominent
child: MyWidget(),
)
Or custom:
theme: ShimmerTheme.custom(
baseColor: Colors.grey[300],
highlightColor: Colors.white,
duration: Duration(milliseconds: 1200),
intensity: 0.6,
)
6οΈβ£ Staggered Effect
StaggeredShimmer(
children: [
SkeletonBox(width: 300, height: 100),
SizedBox(height: 16),
SkeletonLine(width: 250),
SizedBox(height: 8),
SkeletonLine(width: 200),
],
staggerDuration: Duration(milliseconds: 200),
)
π¨ Animation Types
AnimationType.shimmer, // Wave effect (default)
AnimationType.pulse, // Fade in/out
AnimationType.combined, // Both effects
π§ 8 Directions
ShimmerDirection.ltr, // Left to Right
ShimmerDirection.rtl, // Right to Left
ShimmerDirection.ttb, // Top to Bottom
ShimmerDirection.btt, // Bottom to Top
ShimmerDirection.diagonalLTR, // Diagonal β
ShimmerDirection.diagonalRTL, // Diagonal β
ShimmerDirection.diagonalBLTR, // Diagonal β
ShimmerDirection.wave, // Wave pattern
βοΈ Smart Configuration Strategies
Clean, semantic API using enums:
SmartSkeletonConfig(
// What to replace?
replacementStrategy: SkeletonReplacementStrategy.textAndImages,
// Fill empty space?
fillingStrategy: FillingStrategy.spaceOnly,
// Cache performance?
cacheStrategy: CacheStrategy.enabled,
// Allow nesting?
nestingStrategy: NestingStrategy.limited,
)
π§ Advanced Features
Nested Skeletons
SmartSkeleton(
loading: outerLoading,
child: SmartSkeleton(
loading: innerLoading,
child: InnerWidget(),
),
)
Performance Optimization
SmartSkeletonConfig(
cacheStrategy: CacheStrategy.aggressive,
)
final stats = SmartSkeleton.getCacheStats();
SmartSkeleton.clearCache();
Testing Utilities
import 'package:adaptive_shimmer/testing_utils.dart';
ShimmerTester.findSkeletonWidgets(context);
ShimmerTester.countSkeletonsByType(context);
ShimmerTester.verifySkeletonCount(context, expected: 5);
Custom Transformers
SmartSkeleton(
loading: isLoading,
config: SmartSkeletonConfig(
customTransformers: [
SkeletonTransformer(
predicate: (w) => w is MyCustomWidget,
transformer: (w) => SkeletonBox(width: 200, height: 100),
priority: 10,
),
],
),
child: YourWidget(),
)
π¦ Pre-built Components
SkeletonBox(width: 100, height: 100) // Rectangle
SkeletonCircle(radius: 40) // Circle
SkeletonLine(width: 200, height: 12) // Text line
SkeletonParagraph(width: double.infinity) // Multi-line
ScreenShimmer(...) // Full-page loading
ShimmerTransition(...) // Smooth fade-in
StaggeredShimmer(...) // Cascade effect
CollectionSkeleton(...) // List/grid skeletons
π‘ Best Practices
β
Use SmartSkeleton for auto-detection
β
Set realistic itemCount for collections
β
Theme consistently with presets
β
Motion preferences are automatic
β
Cache for high-frequency transforms
β
Test with testing utilities
π― Use Cases
β E-commerce products
β Social media feeds
β Search results
β User profiles
β News articles
β Chat messages
β Data tables
β Dashboards
β‘ Performance
- GPU-accelerated animations (ShaderMask)
- Built-in transformation caching
- Zero re-renders on rebuilds
- ~10KB package size (no dependencies)
π Real-World Examples
E-commerce Product List
ScreenShimmer(
loading: isLoadingProducts,
child: ListView.builder(
itemCount: products.length,
itemBuilder: (_, i) => ProductCard(product: products[i]),
),
)
Social Media Feed
StaggeredShimmer(
children: List.generate(3, (_) => ShimmerBox(width: double.infinity, height: 300)),
staggerDuration: Duration(milliseconds: 150),
)
User Profile
ShimmerTransition(
loading: isLoadingProfile,
loadingChild: SkeletonProfilePage(),
child: ProfilePage(user: user),
)
π Troubleshooting
Shimmer appears too bright/dim
Adjust the intensity parameter (0.0 - 1.0).
Animation is too fast/slow
Modify the duration parameter.
Widget not shimmering on ScreenShimmer
Ensure it's not wrapped with ShimmerExclude.
π License
MIT License - See LICENSE file for details
π€ Contributing
Found a bug or have a feature idea? Contributions are welcome!
π¬ Support & Feedback
Love this package? Please help:
- β Star on GitHub
- π Like on pub.flutter-io.cn
- π Report bugs or request features
- π’ Share with the Flutter community
- β Buy me a coffee
Built with β€οΈ by Abhijith )
#### Circle Skeleton
```dart
SkeletonCircle(
radius: 40,
)
Line Skeleton (for text)
SkeletonLine(
width: 150,
height: 10,
)
Screen-Wide Shimmer
Wrap your entire screen to apply shimmer to all components:
ScreenShimmer(
loading: isLoading,
child: Scaffold(
appBar: AppBar(title: Text('My App')),
body: SingleChildScrollView(
child: Column(
children: [
// All widgets inside will shimmer during loading
Text('Content'),
Image.network('...'),
// ... more widgets
],
),
),
),
)
Excluding Widgets from Screen Shimmer
Use ShimmerExclude to keep certain widgets visible during screen shimmer:
ScreenShimmer(
loading: isLoading,
child: Scaffold(
appBar: AppBar(title: Text('My App')),
body: Column(
children: [
// This will shimmer
ShimmerBox(width: 200, height: 100),
// This will NOT shimmer - visible during loading
ShimmerExclude(
child: ElevatedButton(
onPressed: () {},
child: Text('Retry'),
),
),
// This will shimmer
ShimmerLine(width: 300),
],
),
),
)
Animation Types
Shimmer (Default)
Classic left-to-right shimmer wave effect.
AdaptiveShimmer(
loading: true,
animationType: AnimationType.shimmer,
child: MyWidget(),
)
Pulse
Fading in and out effect.
AdaptiveShimmer(
loading: true,
animationType: AnimationType.pulse,
child: MyWidget(),
)
Combined
Shimmer + pulse effect for enhanced visual feedback.
AdaptiveShimmer(
loading: true,
animationType: AnimationType.combined,
child: MyWidget(),
)
Customization
Custom Colors
AdaptiveShimmer(
loading: true,
baseColor: Color(0xFFE0E0E0),
highlightColor: Color(0xFFF5F5F5),
child: MyWidget(),
)
Custom Animation Duration
AdaptiveShimmer(
loading: true,
duration: Duration(milliseconds: 1000),
child: MyWidget(),
)
Disable Animation
AdaptiveShimmer(
loading: true,
enabled: false,
child: MyWidget(),
)
Advanced Example: Product Card
Container(
padding: EdgeInsets.all(12),
child: Row(
children: [
SkeletonCircle(radius: 40),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SkeletonLine(width: 150, height: 12),
SizedBox(height: 8),
SkeletonParagraph(
width: double.infinity,
lineCount: 2,
lineHeight: 10,
),
],
),
),
],
),
)
π License
MIT License - feel free to use in commercial projects
π€ Contributing
Found a bug or have a feature idea? Contributions welcome!