Jaime Blasco
Committed by GitHub

Merge pull request #8 from jamesblasco/scroll-end-velocity

Add support to close a modal with a scroll view by dragging fast
@@ -178,7 +178,6 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -178,7 +178,6 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
178 final canClose = await shouldClose(); 178 final canClose = await shouldClose();
179 if (canClose) { 179 if (canClose) {
180 _close(); 180 _close();
181 - print('close');  
182 return; 181 return;
183 } else { 182 } else {
184 _cancelClose(); 183 _cancelClose();
@@ -213,13 +212,11 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -213,13 +212,11 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
213 // If speed is bigger than _minFlingVelocity try to close it 212 // If speed is bigger than _minFlingVelocity try to close it
214 if (velocity > _minFlingVelocity) { 213 if (velocity > _minFlingVelocity) {
215 _close(); 214 _close();
216 - print('close2');  
217 } else if (hasReachedCloseThreshold) { 215 } else if (hasReachedCloseThreshold) {
218 if (widget.animationController.value > 0.0) { 216 if (widget.animationController.value > 0.0) {
219 widget.animationController.fling(velocity: -1.0); 217 widget.animationController.fling(velocity: -1.0);
220 } 218 }
221 _close(); 219 _close();
222 - print('close3');  
223 } else { 220 } else {
224 _cancelClose(); 221 _cancelClose();
225 } 222 }
@@ -228,6 +225,14 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -228,6 +225,14 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
228 } 225 }
229 } 226 }
230 227
  228 +
  229 + // As we cannot access the dragGesture detector of the scroll view
  230 + // we can not know the DragDownDetails and therefore the end velocity.
  231 + // VelocityTracker it is used to calculate the end velocity of the scroll
  232 + // when user is trying to close the modal by dragging
  233 + VelocityTracker _velocityTracker;
  234 + DateTime _startTime;
  235 +
231 void _handleScrollUpdate(ScrollNotification notification) { 236 void _handleScrollUpdate(ScrollNotification notification) {
232 if (notification.metrics.pixels <= notification.metrics.minScrollExtent) { 237 if (notification.metrics.pixels <= notification.metrics.minScrollExtent) {
233 //Check if listener is same from scrollController 238 //Check if listener is same from scrollController
@@ -237,6 +242,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -237,6 +242,10 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
237 return; 242 return;
238 } 243 }
239 DragUpdateDetails dragDetails; 244 DragUpdateDetails dragDetails;
  245 + if (notification is ScrollStartNotification) {
  246 + _velocityTracker = VelocityTracker();
  247 + _startTime = DateTime.now();
  248 + }
240 if (notification is ScrollUpdateNotification) { 249 if (notification is ScrollUpdateNotification) {
241 dragDetails = notification.dragDetails; 250 dragDetails = notification.dragDetails;
242 } 251 }
@@ -244,12 +253,15 @@ class _ModalBottomSheetState extends State<ModalBottomSheet> @@ -244,12 +253,15 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
244 dragDetails = notification.dragDetails; 253 dragDetails = notification.dragDetails;
245 } 254 }
246 if (dragDetails != null) { 255 if (dragDetails != null) {
247 - print('scroll'); 256 + final duration = _startTime.difference(DateTime.now());
  257 + final offset = Offset(0, _scrollController.offset);
  258 + _velocityTracker.addPosition(duration, offset);
248 _handleDragUpdate(dragDetails.primaryDelta); 259 _handleDragUpdate(dragDetails.primaryDelta);
249 } 260 }
250 - // Todo: detect dragEnd during scroll so it can bottom sheet can close  
251 - // if velocity > _minFlingVelocity  
252 - else if (isDragging) _handleDragEnd(0); 261 + else if (isDragging) {
  262 + final velocity = _velocityTracker.getVelocity().pixelsPerSecond.dy;
  263 + _handleDragEnd(velocity);
  264 + }
253 } 265 }
254 } 266 }
255 267