Skip to content

Instantly share code, notes, and snippets.

@esDotDev
Last active March 8, 2020 19:05
Show Gist options
  • Save esDotDev/792425c2cdfef947ce514b8ab70511e6 to your computer and use it in GitHub Desktop.
Save esDotDev/792425c2cdfef947ce514b8ab70511e6 to your computer and use it in GitHub Desktop.
flutter_scrollbar_performance_spike - Demonstrates performance issues detailed here: https://github.com/flutter/flutter/issues/52207
import 'package:flutter/material.dart';
class ScrollbarSpike extends StatefulWidget {
@override
_ScrollbarSpikeState createState() => _ScrollbarSpikeState();
}
class _ScrollbarSpikeState extends State<ScrollbarSpike> {
static List<String> items = List.generate(10000, (index) => "List Item: $index");
ScrollController scrollController;
@override
void initState() {
scrollController = ScrollController();
super.initState();
}
@override
Widget build(BuildContext context) {
double scrollerWidth = 20;
return Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: scrollerWidth),
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: items.length,
controller: scrollController,
itemBuilder: (_, index) => Text(items[index]))),
Scrollbar(width: scrollerWidth, controller: scrollController)
],
);
}
}
class Scrollbar extends StatefulWidget {
final double width;
final ScrollController controller;
const Scrollbar({Key key, this.width, this.controller}) : super(key: key);
@override
_ScrollbarState createState() => _ScrollbarState();
}
class _ScrollbarState extends State<Scrollbar> {
double _viewHeight = 100;
@override
void initState() {
widget.controller.addListener(() => setState(() {}));
super.initState();
}
@override
Widget build(BuildContext context) {
double offset = widget.controller.offset / (widget.controller?.position?.maxScrollExtent ?? 1);
return LayoutBuilder(
builder: (_, BoxConstraints constraints) {
_viewHeight = constraints.maxHeight;
return Stack(children: <Widget>[
Align(
alignment: Alignment(1, 1),
child: Container(color: Colors.red, width: widget.width, height: double.infinity),
),
Align(
alignment: Alignment(1, -1 + offset * 2),
child: GestureDetector(
onVerticalDragUpdate: _handleVerticalDrag, child: Container(width: widget.width, height: 40, color: Colors.green)),
)
]);
},
);
}
void _handleVerticalDrag(DragUpdateDetails details) {
double pos = widget.controller.offset;
double pxRatio = widget.controller.position.maxScrollExtent / _viewHeight;
widget.controller.jumpTo((pos + details.delta.dy * pxRatio).clamp(0, widget.controller.position.maxScrollExtent));
//print(pos + details.delta.dx * pxRatio);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment