🧭 Scrollbar Magic in Flutter: Animations, Cupertino Style & Scroll-to-Top Button
Flutter gives you fine-grained control over scroll behaviors. This blog post explores:
- Animated scrollbar thumb
- iOS-style
CupertinoScrollbar
- A floating scroll-to-top button
1️⃣ Using Scrollbar with Animation
We use the Scrollbar
widget with a ScrollController
. Flutter's default scrollbar supports animation starting from Flutter 2.0+.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Scrollbar Demo',
home: AnimatedScrollbarList(),
);
}
}
class AnimatedScrollbarList extends StatefulWidget {
@override
_AnimatedScrollbarListState createState() => _AnimatedScrollbarListState();
}
class _AnimatedScrollbarListState extends State<AnimatedScrollbarList> {
final ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Animated Scrollbar')),
body: Scrollbar(
controller: _controller,
thumbVisibility: true,
thickness: 8,
radius: Radius.circular(10),
child: ListView.builder(
controller: _controller,
itemCount: 100,
itemBuilder: (context, index) => ListTile(
title: Text('Item \$index'),
),
),
),
);
}
}
2️⃣ iOS-Style CupertinoScrollbar
For iOS consistency, use CupertinoScrollbar
from flutter/cupertino.dart
. It auto-adjusts to the platform’s look.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(CupertinoApp(home: CupertinoScrollPage()));
class CupertinoScrollPage extends StatelessWidget {
final ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(middle: Text('Cupertino Scrollbar')),
child: CupertinoScrollbar(
controller: _controller,
thickness: 6,
radius: Radius.circular(8),
child: ListView.builder(
controller: _controller,
itemCount: 50,
itemBuilder: (context, index) =>
ListTile(title: Text('Item \$index')),
),
),
);
}
}
3️⃣ Floating Scroll-to-Top Button
This button appears after scrolling down. Clicking it scrolls back to the top smoothly.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: ScrollToTopDemo()));
class ScrollToTopDemo extends StatefulWidget {
@override
_ScrollToTopDemoState createState() => _ScrollToTopDemoState();
}
class _ScrollToTopDemoState extends State<ScrollToTopDemo> {
final ScrollController _controller = ScrollController();
bool _showButton = false;
@override
void initState() {
super.initState();
_controller.addListener(() {
setState(() {
_showButton = _controller.offset > 300;
});
});
}
void _scrollToTop() {
_controller.animateTo(0,
duration: Duration(milliseconds: 500),
curve: Curves.easeInOut);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Scroll to Top')),
body: ListView.builder(
controller: _controller,
itemCount: 100,
itemBuilder: (context, index) => ListTile(title: Text('Item \$index')),
),
floatingActionButton: _showButton
? FloatingActionButton(
onPressed: _scrollToTop,
child: Icon(Icons.arrow_upward),
tooltip: 'Scroll to top',
)
: null,
);
}
}
🧠 Recap
- Use
Scrollbar
with animation for smooth feedback - For iOS design fidelity,
CupertinoScrollbar
is the go-to - Scroll-to-top buttons enhance long list UX
💡 Bonus Tips
- Use
NotificationListener<ScrollNotification>
to detect scrolling - Customize scrollbar color with
ThemeData.scrollbarTheme
0 Comments