Skip to content

Instantly share code, notes, and snippets.

@mashik424
Created January 21, 2022 08:22
Show Gist options
  • Save mashik424/c1ee074526f45182bcb2c4fb44c7a673 to your computer and use it in GitHub Desktop.
Save mashik424/c1ee074526f45182bcb2c4fb44c7a673 to your computer and use it in GitHub Desktop.
Flutter: Animated PageView Progress Bar
import 'package:flutter/material.dart';
class PageProgress extends StatefulWidget implements PreferredSizeWidget {
const PageProgress({
Key? key,
required this.context,
required this.pageCount,
this.pageController,
this.progress,
this.duration,
}) : assert(pageController != null ||
(progress != null && progress >= 0.0 && progress <= 1.0)),
assert(pageCount > 1),
super(key: key);
final BuildContext context;
final double? progress;
final PageController? pageController;
final int pageCount;
final Duration? duration;
@override
Size get preferredSize => Size(
MediaQuery.of(context).size.width,
13,
);
@override
State<PageProgress> createState() => _PageProgressState();
}
class _PageProgressState extends State<PageProgress> {
double _progress = 0.0;
@override
void initState() {
WidgetsBinding.instance
?.addPostFrameCallback((timeStamp) => initProgress());
super.initState();
}
void initProgress() {
if (widget.pageController != null) {
final maxOffset = MediaQuery.of(context).size.width * widget.pageCount;
setState(() {
_progress = 1 / widget.pageCount;
});
widget.pageController?.addListener(() {
setState(() {
_progress = (1 / widget.pageCount) +
(widget.pageController!.offset / maxOffset);
});
});
}
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Container(
margin: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 5,
),
width: double.infinity,
height: 3.0,
decoration: BoxDecoration(
color: Colors.blueGrey.shade200,
borderRadius: BorderRadius.circular(5),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 5,
),
child: LayoutBuilder(
builder: (context, constraints) => AnimatedContainer(
duration: widget.duration ?? const Duration(milliseconds: 1),
width: widget.progress == null
? (constraints.maxWidth * _progress)
: (constraints.maxWidth * widget.progress!),
height: 3.0,
decoration: BoxDecoration(
color: Colors.deepPurple.shade900,
borderRadius: BorderRadius.circular(5),
),
),
),
),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment