Created
December 3, 2018 05:01
-
-
Save happyharis/49d363401441f66c7f9fa3fde98da34e to your computer and use it in GitHub Desktop.
This file contains 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'; | |
import 'package:flutter/gestures.dart'; | |
void main() => runApp(new MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
theme: new ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: new Scaffold( | |
appBar: new AppBar( | |
title: new Text('Draggable Scroll Bar Demo'), | |
), | |
//DraggableScrollbar builds Stack with provided Scrollable List of Grid | |
body: new DraggableScrollbar( | |
child: _buildGrid(), | |
), | |
), | |
); | |
} | |
Widget _buildGrid() { | |
return GridView.builder( | |
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( | |
crossAxisCount: 5, | |
), | |
padding: EdgeInsets.zero, | |
itemCount: 1000, | |
itemBuilder: (context, index) { | |
return Container( | |
alignment: Alignment.center, | |
margin: EdgeInsets.all(2.0), | |
color: Colors.grey[300], | |
); | |
}, | |
); | |
} | |
} | |
class DraggableScrollbar extends StatefulWidget { | |
const DraggableScrollbar({this.child}); | |
final Widget child; | |
@override | |
_DraggableScrollbarState createState() => new _DraggableScrollbarState(); | |
} | |
class _DraggableScrollbarState extends State<DraggableScrollbar> | |
with TickerProviderStateMixin { | |
//this counts offset for scroll thumb for Vertical axis | |
double _barOffset; | |
// controller for the thing | |
AnimationController animationController; | |
Animation<double> animation; | |
@override | |
void initState() { | |
super.initState(); | |
animationController = | |
AnimationController(vsync: this, duration: Duration(seconds: 1)); | |
_barOffset = 300.0; | |
} | |
void _onVerticalDragUpdate(DragUpdateDetails details) { | |
setState(() { | |
_barOffset += details.delta.dy; | |
}); | |
} | |
void _animateSelectorBack() { | |
if (mounted) { | |
setState(() { | |
_barOffset = animation.value; | |
}); | |
} | |
} | |
void _verticalGoesBack(DragEndDetails details) { | |
animationController.reset(); | |
animation = Tween<double>(begin: _barOffset, end: 300.0) | |
.animate(animationController) | |
..addListener(_animateSelectorBack) | |
..addStatusListener((status) { | |
if (status == AnimationStatus.completed) { | |
animationController.removeListener(_animateSelectorBack); | |
} | |
}); | |
animationController.forward(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return new Stack(children: <Widget>[ | |
widget.child, | |
GestureDetector( | |
onVerticalDragUpdate: _onVerticalDragUpdate, | |
onVerticalDragEnd: _verticalGoesBack, | |
child: Container( | |
alignment: Alignment.topRight, | |
margin: EdgeInsets.only(top: _barOffset), | |
child: _buildScrollThumb())), | |
]); | |
} | |
Widget _buildScrollThumb() { | |
return new Container( | |
height: 40.0, | |
width: 20.0, | |
color: Colors.blue, | |
); | |
} | |
@override | |
void dispose() { | |
super.dispose(); | |
animationController.dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment