This repository has been archived by the owner on Nov 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
21fffcb
commit bc0f325
Showing
8 changed files
with
249 additions
and
50 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:snapping_sheet/snapping_sheet.dart'; | ||
import 'package:snapping_sheet/src/sheet_size_calculator.dart'; | ||
import 'package:snapping_sheet/src/snapping_calculator.dart'; | ||
|
||
class ScrollControllerOverride extends StatefulWidget { | ||
final SheetSizeCalculator sizeCalculator; | ||
final ScrollController scrollController; | ||
final SheetLocation sheetLocation; | ||
final Widget child; | ||
|
||
final Function(double) dragUpdate; | ||
final VoidCallback dragEnd; | ||
final double currentPosition; | ||
final SnappingCalculator snappingCalculator; | ||
|
||
ScrollControllerOverride({ | ||
required this.sizeCalculator, | ||
required this.scrollController, | ||
required this.dragUpdate, | ||
required this.dragEnd, | ||
required this.currentPosition, | ||
required this.snappingCalculator, | ||
required this.child, | ||
required this.sheetLocation, | ||
}); | ||
|
||
@override | ||
_ScrollControllerOverrideState createState() => | ||
_ScrollControllerOverrideState(); | ||
} | ||
|
||
class _ScrollControllerOverrideState extends State<ScrollControllerOverride> { | ||
DragDirection? _currentDragDirection; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
widget.scrollController.removeListener(_onScrollUpdate); | ||
widget.scrollController.addListener(_onScrollUpdate); | ||
} | ||
|
||
@override | ||
void dispose() { | ||
widget.scrollController.removeListener(_onScrollUpdate); | ||
super.dispose(); | ||
} | ||
|
||
void _onScrollUpdate() { | ||
if (!_allowScrolling) _lockScrollPosition(widget.scrollController); | ||
} | ||
|
||
void _overrideScroll(double dragAmount) { | ||
if (!_allowScrolling) widget.dragUpdate(dragAmount); | ||
} | ||
|
||
bool get _allowScrolling { | ||
if (widget.sheetLocation == SheetLocation.below) { | ||
if (_currentDragDirection == DragDirection.up) { | ||
if (widget.currentPosition >= _biggestSnapPos) | ||
return true; | ||
else | ||
return false; | ||
} | ||
if (_currentDragDirection == DragDirection.down) { | ||
if (widget.scrollController.position.pixels > 0) return true; | ||
if (widget.currentPosition <= _smallestSnapPos) | ||
return true; | ||
else | ||
return false; | ||
} | ||
} | ||
|
||
if (widget.sheetLocation == SheetLocation.above) { | ||
if (_currentDragDirection == DragDirection.down) { | ||
if (widget.currentPosition <= _smallestSnapPos) { | ||
return true; | ||
} else | ||
return false; | ||
} | ||
if (_currentDragDirection == DragDirection.up) { | ||
if (widget.scrollController.position.pixels > 0) return true; | ||
if (widget.currentPosition >= _biggestSnapPos) | ||
return true; | ||
else | ||
return false; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
double get _biggestSnapPos => | ||
widget.snappingCalculator.getBiggestPositionPixels(); | ||
double get _smallestSnapPos => | ||
widget.snappingCalculator.getSmallestPositionPixels(); | ||
|
||
void _lockScrollPosition(ScrollController controller) { | ||
controller.position.setPixels(0); | ||
} | ||
|
||
void _setDragDirection(double dragAmount) { | ||
this._currentDragDirection = | ||
dragAmount > 0 ? DragDirection.down : DragDirection.up; | ||
print(this._currentDragDirection); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Listener( | ||
onPointerMove: (dragEvent) { | ||
_setDragDirection(dragEvent.delta.dy); | ||
_overrideScroll(dragEvent.delta.dy); | ||
}, | ||
onPointerUp: (_) { | ||
widget.dragEnd(); | ||
}, | ||
child: widget.child, | ||
); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,71 @@ | ||
import 'package:flutter/widgets.dart'; | ||
import 'package:snapping_sheet/src/on_drag_wrapper.dart'; | ||
import 'package:snapping_sheet/src/scroll_controller_override.dart'; | ||
import 'package:snapping_sheet/src/sheet_size_calculator.dart'; | ||
import 'package:snapping_sheet/src/snapping_calculator.dart'; | ||
import 'package:snapping_sheet/src/snapping_sheet_content.dart'; | ||
|
||
class SheetContentWrapper extends StatelessWidget { | ||
class SheetContentWrapper extends StatefulWidget { | ||
final SheetSizeCalculator sizeCalculator; | ||
final SnappingSheetContent? sheetData; | ||
|
||
final Function(double) dragUpdate; | ||
final VoidCallback dragStart; | ||
final VoidCallback dragEnd; | ||
final double currentPosition; | ||
final SnappingCalculator snappingCalculator; | ||
|
||
const SheetContentWrapper( | ||
{Key? key, | ||
required this.sheetData, | ||
required this.sizeCalculator, | ||
required this.currentPosition, | ||
required this.snappingCalculator, | ||
required this.dragUpdate, | ||
required this.dragStart, | ||
required this.dragEnd}) | ||
: super(key: key); | ||
|
||
Widget _wrapSheetDataWithDraggable() { | ||
if (!sheetData!.draggable) return sheetData!; | ||
@override | ||
_SheetContentWrapperState createState() => _SheetContentWrapperState(); | ||
} | ||
|
||
class _SheetContentWrapperState extends State<SheetContentWrapper> { | ||
Widget _wrapWithDragWrapper(Widget child) { | ||
return OnDragWrapper( | ||
dragStart: dragStart, | ||
dragEnd: dragEnd, | ||
child: sheetData!, | ||
dragUpdate: dragUpdate, | ||
dragEnd: widget.dragEnd, | ||
child: child, | ||
dragUpdate: widget.dragUpdate, | ||
); | ||
} | ||
|
||
Widget _wrapWithScrollControllerOverride(Widget child) { | ||
return ScrollControllerOverride( | ||
sizeCalculator: widget.sizeCalculator, | ||
scrollController: widget.sheetData!.childScrollController!, | ||
dragUpdate: widget.dragUpdate, | ||
dragEnd: widget.dragEnd, | ||
currentPosition: widget.currentPosition, | ||
snappingCalculator: widget.snappingCalculator, | ||
sheetLocation: widget.sheetData!.location, | ||
child: child, | ||
); | ||
} | ||
|
||
Widget _wrapWithNecessaryWidgets(Widget child) { | ||
Widget wrappedChild = child; | ||
if (widget.sheetData!.draggable) { | ||
wrappedChild = _wrapWithDragWrapper(wrappedChild); | ||
} | ||
if (widget.sheetData!.childScrollController != null) { | ||
wrappedChild = _wrapWithScrollControllerOverride(wrappedChild); | ||
} | ||
return wrappedChild; | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
if (sheetData == null) return SizedBox(); | ||
return sizeCalculator.positionWidget(child: _wrapSheetDataWithDraggable()); | ||
if (widget.sheetData == null) return SizedBox(); | ||
return widget.sizeCalculator.positionWidget( | ||
child: _wrapWithNecessaryWidgets(widget.sheetData!.child), | ||
); | ||
} | ||
} |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,45 @@ | ||
import 'package:flutter/widgets.dart'; | ||
import 'sheet_size_behaviors.dart'; | ||
|
||
enum SnappingSheetContentSize { | ||
// The size of the sheet content changes to the available height | ||
dynamicSize, | ||
|
||
/// The size is static and do not change when the sheet is dragged | ||
staticSize, | ||
enum SheetLocation { | ||
above, | ||
below, | ||
unknown, | ||
} | ||
|
||
class SnappingSheetContent extends StatelessWidget { | ||
class SnappingSheetContent { | ||
/// The size behavior of the sheet. Can either be [SheetSizeStatic] or | ||
/// [SheetSizeDynamic]. | ||
final SheetSizeBehavior sizeBehavior; | ||
final Widget child; | ||
|
||
/// When given a scroll controller that is attached to scrollable view, e.g | ||
/// [ListView] or a [SingleChildScrollView], the sheet will naturally grow | ||
/// and shrink according to the current scroll position of that view. | ||
/// | ||
/// OBS, the scrollable view needs to have the [reverse] parameter set to | ||
/// false if located in the below sheet and true if located in the above | ||
/// sheet. Otherwise, the logic wont behave as intended. | ||
final ScrollController? childScrollController; | ||
final bool draggable; | ||
Widget _child; | ||
SheetLocation location = SheetLocation.unknown; | ||
|
||
SnappingSheetContent({ | ||
Key? key, | ||
required this.child, | ||
required Widget child, | ||
this.draggable = false, | ||
this.sizeBehavior = const SheetSizeDynamic(), | ||
}) : super(key: key); | ||
this.childScrollController, | ||
}) : this._child = child; | ||
|
||
double? _getHeight() { | ||
var sizeBehavior = this.sizeBehavior; | ||
if (sizeBehavior is SheetSizeStatic) return sizeBehavior.height; | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
Widget get child { | ||
return SizedBox( | ||
height: _getHeight(), | ||
child: this.child, | ||
child: this._child, | ||
); | ||
} | ||
} |
Oops, something went wrong.