Last active
March 8, 2020 19:05
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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