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: