Skip to content

Instantly share code, notes, and snippets.

@austinevick
Last active January 11, 2024 10:47
Show Gist options
  • Save austinevick/d53857dc6aa02d49e19757390d953526 to your computer and use it in GitHub Desktop.
Save austinevick/d53857dc6aa02d49e19757390d953526 to your computer and use it in GitHub Desktop.
Programmatically scroll to top
class ScrollToTopWidgetWrapper extends StatefulWidget {
final Widget child;
const ScrollToTopWidgetWrapper({super.key, required this.child});
@override
State<ScrollToTopWidgetWrapper> createState() =>
_ScrollToTopWidgetWrapperState();
}
class _ScrollToTopWidgetWrapperState extends State<ScrollToTopWidgetWrapper> {
final scrollController = ScrollController();
bool isVisible = false;
@override
void initState() {
scrollController.addListener(_scrollListener);
super.initState();
}
_scrollListener() {
if (scrollController.offset > 0.0) {
setState(() {
isVisible = true;
});
}
if (scrollController.offset <= 0.0) {
setState(() {
isVisible = false;
});
}
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SingleChildScrollView(
controller: scrollController, child: widget.child),
isVisible
? Positioned(
bottom: 16,
right: 8,
child: AnimatedFloatingButton(
onPressed: () => scrollController.animateTo(0.0,
duration: Durations.long4, curve: Curves.easeInOut)),
)
: const Center()
],
);
}
}
class AnimatedFloatingButton extends StatefulWidget {
final VoidCallback onPressed;
const AnimatedFloatingButton({super.key, required this.onPressed});
@override
State<AnimatedFloatingButton> createState() => _AnimatedFloatingButtonState();
}
class _AnimatedFloatingButtonState extends State<AnimatedFloatingButton>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<Offset> animation;
@override
void initState() {
super.initState();
_controller =
AnimationController(vsync: this, duration: const Duration(seconds: 4));
animation =
Tween(begin: const Offset(5, 0), end: const Offset(0, 0)).animate(_controller);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SlideTransition(
position: animation,
child: CustomButton(
color: Colors.green,
height: 60,
width: 60,
radius: 50,
onPressed: widget.onPressed,
child: const Icon(
Icons.keyboard_arrow_up,
size: 34,
color: Colors.white,
)),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment