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