diff --git a/CHANGELOG.md b/CHANGELOG.md index 7569efb..3e8d01f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,6 @@ -# 4.3.1 Release +# 4.4.0 Release -- Update document -- Change `ScrollableManager`'s `bool? enableExpandedScroll` to `bool enableExpandedScroll` +- Add `smoothScrolling` parameter to `ScrollableManager`. (New Smooth Scrolling Feature) ## 4.3.0 Release diff --git a/README.md b/README.md index 2e5388c..36f95bc 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@

- + - +

@@ -274,7 +274,7 @@ DraggableMenu( In short, do not forget to use `ScrollableManager` and set the physics of the scrollable you want to `NeverScrollableScrollPhysics`. -Extra: *Check out the `ScrollableManager`'s `enableExpandedScroll` parameter.* +Extra: *Check out the `ScrollableManager`'s `enableExpandedScroll` and `smoothScrolling` parameters.* --- diff --git a/example/lib/main.dart b/example/lib/main.dart index 85c0ed7..7d87c21 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -29,6 +29,7 @@ class _AppState extends State { bool _enableExpandedScroll = false; bool _fastDrag = true; bool _minimizeBeforeFastDrag = false; + bool _smoothScrolling = false; @override Widget build(BuildContext context) { @@ -57,6 +58,9 @@ class _AppState extends State { const SizedBox(height: 8), _boolRow("Barrier", _barrier, (value) => _barrier = value), const SizedBox(height: 8), + _boolRow("Smooth Scrolling", _smoothScrolling, + (value) => _smoothScrolling = value), + const SizedBox(height: 8), const Text( "UI Type:", style: TextStyle( @@ -153,6 +157,7 @@ class _AppState extends State { fastDrag: _fastDrag, enableExpandedScroll: _enableExpandedScroll, minimizeBeforeFastDrag: _minimizeBeforeFastDrag, + smoothScrolling: _smoothScrolling, ), barrier: _barrier, ), @@ -166,6 +171,7 @@ class _AppState extends State { fastDrag: _fastDrag, enableExpandedScroll: _enableExpandedScroll, minimizeBeforeFastDrag: _minimizeBeforeFastDrag, + smoothScrolling: _smoothScrolling, ), barrier: _barrier, ), diff --git a/example/lib/menus/custom/scrollable.dart b/example/lib/menus/custom/scrollable.dart index a57f37d..d690bcc 100644 --- a/example/lib/menus/custom/scrollable.dart +++ b/example/lib/menus/custom/scrollable.dart @@ -7,6 +7,7 @@ class ScrollableMenu extends StatelessWidget { final bool enableExpandedScroll; final bool fastDrag; final bool minimizeBeforeFastDrag; + final bool smoothScrolling; const ScrollableMenu({ super.key, @@ -14,6 +15,7 @@ class ScrollableMenu extends StatelessWidget { required this.enableExpandedScroll, required this.fastDrag, required this.minimizeBeforeFastDrag, + required this.smoothScrolling, }); @override @@ -23,6 +25,7 @@ class ScrollableMenu extends StatelessWidget { fastDrag: fastDrag, minimizeBeforeFastDrag: minimizeBeforeFastDrag, child: ScrollableManager( + smoothScrolling: smoothScrolling, enableExpandedScroll: enableExpandedScroll, child: ListView.builder( physics: const NeverScrollableScrollPhysics(), diff --git a/example/lib/menus/custom/two_scrollable.dart b/example/lib/menus/custom/two_scrollable.dart index 7ab6a81..b5720a4 100644 --- a/example/lib/menus/custom/two_scrollable.dart +++ b/example/lib/menus/custom/two_scrollable.dart @@ -7,6 +7,7 @@ class TwoScrollableMenu extends StatelessWidget { final bool enableExpandedScroll; final bool fastDrag; final bool minimizeBeforeFastDrag; + final bool smoothScrolling; const TwoScrollableMenu({ super.key, @@ -14,6 +15,7 @@ class TwoScrollableMenu extends StatelessWidget { required this.enableExpandedScroll, required this.fastDrag, required this.minimizeBeforeFastDrag, + required this.smoothScrolling, }); @override @@ -31,6 +33,7 @@ class TwoScrollableMenu extends StatelessWidget { child: ColoredBox( color: Colors.indigoAccent, child: ScrollableManager( + smoothScrolling: smoothScrolling, enableExpandedScroll: enableExpandedScroll, child: ListView.builder( physics: const NeverScrollableScrollPhysics(), @@ -53,6 +56,7 @@ class TwoScrollableMenu extends StatelessWidget { child: ColoredBox( color: Colors.indigoAccent, child: ScrollableManager( + smoothScrolling: smoothScrolling, enableExpandedScroll: enableExpandedScroll, child: ListView.builder( physics: const NeverScrollableScrollPhysics(), diff --git a/lib/src/draggable_menu/utils/scrollable_manager/scrollable_manager.dart b/lib/src/draggable_menu/utils/scrollable_manager/scrollable_manager.dart index 5d638dd..edc0fd9 100644 --- a/lib/src/draggable_menu/utils/scrollable_manager/scrollable_manager.dart +++ b/lib/src/draggable_menu/utils/scrollable_manager/scrollable_manager.dart @@ -14,10 +14,11 @@ class ScrollableManager extends StatefulWidget { /// Only work if the `DraggableMenu`'s expandable feature can work. /// /// If it can work, it will block its scrollable child's drag-up gesture when the Draggable Menu's status isn't `expanded`. - /// - /// By default, it is `false`. final bool enableExpandedScroll; + /// Scrolls the scrollable as soon as the `DraggableMenu` reaches to the top. + final bool smoothScrolling; + /// The `controller` parameter allows you to use a `ScrollController` with the scrollable under it. final ScrollController? controller; @@ -56,6 +57,7 @@ class ScrollableManager extends StatefulWidget { required this.child, this.enableExpandedScroll = false, this.controller, + this.smoothScrolling = false, }); @override @@ -130,9 +132,26 @@ class _ScrollableManagerState extends State { if (details.primaryDelta == null) return; if (_isOverScrolling) { + // Smooth Scrolling + if (widget.smoothScrolling && + _manager.status == DraggableMenuStatus.expanded && + details.primaryDelta!.sign < 0) { + _isOverScrolling = false; + _handleStart(details); + return; + } // Moves the `DraggableMenu` widget. _manager.onDragUpdate.call(details.globalPosition.dy); } else if (_drag != null) { + // Smooth Scrolling + if (widget.smoothScrolling) { + if (_startEdgeOverscrolling(details)) { + _drag?.cancel(); + _drag = null; + return; + } + } + // Moves the scrollable. _drag!.update(details); } else { @@ -181,17 +200,7 @@ class _ScrollableManagerState extends State { /// starts moving the `DraggableMenu` widget /// instead of trying to scroll the scrollable out of it's extents. void _handleStart(DragUpdateDetails details) { - if (_controller.position.atEdge == true) { - if (details.primaryDelta!.sign > 0 && - _controller.position.pixels == _controller.position.minScrollExtent) { - _startOverScrolling(details); - return; - } else if (details.primaryDelta!.sign < 0 && - _controller.position.pixels == _controller.position.maxScrollExtent) { - _startOverScrolling(details); - return; - } - } + if (_startEdgeOverscrolling(details)) return; // Starts the drag event and assigns it to the `_drag` variable. _drag = _controller.position.drag(DragStartDetails(), () { @@ -209,6 +218,24 @@ class _ScrollableManagerState extends State { // To move the `DraggableMenu` widget. _manager.onDragStart.call(details.globalPosition.dy); } + + /// Moves the `DraggableMenu` widget if the scrollable is being overscrolled. + /// + /// Returns true if the current conditions suits overscrolling. + bool _startEdgeOverscrolling(DragUpdateDetails details) { + if (_controller.position.atEdge == true) { + if (details.primaryDelta!.sign > 0 && + _controller.position.pixels == _controller.position.minScrollExtent) { + _startOverScrolling(details); + return true; + } else if (details.primaryDelta!.sign < 0 && + _controller.position.pixels == _controller.position.maxScrollExtent) { + _startOverScrolling(details); + return true; + } + } + return false; + } } class _DisabledScrollBehavior extends ScrollBehavior { diff --git a/pubspec.yaml b/pubspec.yaml index 89ae6f9..0c374e6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: draggable_menu description: Create Draggable Menus like some popular apps like Instagram, Snapchat, Facebook, Twitter, Youtube etc. You can even make your Draggable Menus look identical to them. -version: 4.3.1 +version: 4.4.0 repository: https://github.com/emresoysuren/draggable_menu environment: