Skip to content

Instantly share code, notes, and snippets.

@liyuqian
Last active July 15, 2020 17:10
Show Gist options
  • Save liyuqian/6fe7a6be4b5035bbdbdba57d3356b43d to your computer and use it in GitHub Desktop.
Save liyuqian/6fe7a6be4b5035bbdbdba57d3356b43d to your computer and use it in GitHub Desktop.
Demo how ScrollablePositionedList can handle big jump much faster than the default ListView
// Demo how ScrollablePositionedList can handle big jump much faster than its ListView counterpart at
// https://gist.github.com/esDotDev/792425c2cdfef947ce514b8ab70511e6
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.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");
ItemScrollController scrollController;
@override
void initState() {
scrollController = ItemScrollController();
super.initState();
}
@override
Widget build(BuildContext context) {
double scrollerWidth = 20;
return Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(right: scrollerWidth),
child: ScrollablePositionedList.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: items.length,
itemScrollController: scrollController,
itemBuilder: (_, index) {
Timeline.startSync('build item $index');
final t = Text(items[index]);
Timeline.finishSync();
return t;
})),
Scrollbar(count: items.length, width: scrollerWidth, controller: scrollController)
],
);
}
}
class Scrollbar extends StatefulWidget {
final int count;
final double width;
final ItemScrollController controller;
Scrollbar({Key key, this.count, this.width, this.controller}) : super(key: key);
@override
_ScrollbarState createState() => _ScrollbarState();
}
class _ScrollbarState extends State<Scrollbar> {
double _viewHeight = 100;
double _scrollProgress = 0.0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
double offset = _scrollProgress;
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) {
setState(() {
_scrollProgress = (_scrollProgress + details.delta.dy / _viewHeight).clamp(0, 1);
widget.controller.jumpTo(index: (widget.count * _scrollProgress).round());
});
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Sample Code'),
),
body: ScrollbarSpike(),
),
);
}
}
void main() {
runApp(MyHomePage());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment