Free copy-paste Loader 007 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_007.dart) and use the widget anywhere in your widget tree.
import 'package:flutter/material.dart';
class Loader007 extends StatefulWidget {
const Loader007({
super.key,
this.width = 130.0,
this.height = 4.0,
this.color = const Color(0xFF0071E2),
this.trackColor = const Color(0x33000000),
this.duration = const Duration(milliseconds: 1000),
});
final double width;
final double height;
final Color color;
final Color trackColor;
final Duration duration;
@override
State<Loader007> createState() => _Loader007State();
}
class _Loader007State extends State<Loader007>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _anim;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration)
..repeat();
_anim = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
}
@override
void didUpdateWidget(covariant Loader007 oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.duration != widget.duration) {
_controller.duration = widget.duration;
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: widget.height,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: widget.trackColor,
borderRadius: BorderRadius.circular(widget.height * 2),
),
child: AnimatedBuilder(
animation: _anim,
builder: (context, _) {
final t = _anim.value;
final double left;
final double right;
if (t <= 0.5) {
left = 0.0;
right = widget.width * (1.0 - 2.0 * t);
} else {
left = widget.width * (2.0 * (t - 0.5));
right = 0.0;
}
return Stack(
children: [
Positioned(
left: left,
right: right,
top: 0,
bottom: 0,
child: DecoratedBox(
decoration: BoxDecoration(
color: widget.color,
borderRadius: BorderRadius.circular(widget.height * 2),
),
),
),
],
);
},
),
);
}
}