Free copy-paste Loader 008 for Flutter: a ready-to-use loader widget with full Dart source code and a live preview. Works on mobile & desktop. No external packages.
Copy the Dart code below into a new file in your Flutter project (for example lib/widgets/loader_008.dart) and use the widget anywhere in your widget tree.
import 'package:flutter/material.dart';
class Loader008 extends StatefulWidget {
const Loader008({
super.key,
this.barWidth = 4.0,
this.barHeight = 50.0,
this.gap = 6.0,
this.colors = const [
Color(0xFF4C86F9),
Color(0xFF49A84C),
Color(0xFFF6BB02),
Color(0xFFF6BB02),
Color(0xFF2196F3),
],
this.duration = const Duration(milliseconds: 1000),
});
final double barWidth;
final double barHeight;
final double gap;
final List<Color> colors;
final Duration duration;
@override
State<Loader008> createState() => _Loader008State();
}
class _Loader008State extends State<Loader008>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration)
..repeat();
}
@override
void didUpdateWidget(covariant Loader008 oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.duration != widget.duration) {
_controller.duration = widget.duration;
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
double _getScaleY(double progress, int index) {
final delayFrac = (index * 100) / widget.duration.inMilliseconds;
final phi = (progress + delayFrac) % 1.0;
if (phi < 0.2) {
return 0.05 + 0.95 * (phi / 0.2);
} else if (phi < 0.4) {
return 1.0 - 0.95 * ((phi - 0.2) / 0.2);
} else {
return 0.05;
}
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _controller,
builder: (context, _) {
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: List.generate(widget.colors.length, (i) {
final scale = _getScaleY(_controller.value, i);
return Padding(
padding: EdgeInsets.symmetric(horizontal: widget.gap / 2),
child: Transform.scale(
scaleY: scale,
alignment: Alignment.center,
child: Container(
width: widget.barWidth,
height: widget.barHeight,
decoration: BoxDecoration(
color: widget.colors[i],
borderRadius: BorderRadius.circular(widget.barWidth / 2),
),
),
),
);
}),
);
},
);
}
}