diff --git a/CHANGELOG.md b/CHANGELOG.md index 9930ee5..81f284c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [4.0.0] + +- **BREAKING CHANGE**: + - CardSwipers onSwipe function now returns `````` instead of ``````. If onSwipe returns ```false```, + the swipe action will now be canceled and the current card will remain on top of the stack. + Otherwise, if it returns ```true```, the swipe action will be performed as expected. + ## [3.1.0] - Adds option to set the initial index of the swiper. diff --git a/README.md b/README.md index 83a32cb..76ab01f 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ class Example extends StatelessWidget { | isVerticalSwipingEnabled | true | Set to ```false``` if you want your card to move only across the horizontal axis when swiping | false | isLoop | true | set to ```true``` if the stack should loop | false | onTapDisabled | - | Function that get triggered when the swiper is disabled | false -| onSwipe | - | Called with the new index and detected swipe direction when the user swiped | false +| onSwipe | - | Called with the oldIndex, newIndex and detected swipe direction when the user swiped. If [onSwipe] returns ```false```, the swipe action will be canceled. Otherwise, if it returns ```true```, the swipe action will be performed as expected. | false | onEnd | - | Called when there is no Widget left to be swiped away | false | direction | right | Direction in which the card is swiped away when triggered from the outside | false | numberOfCardsDisplayed | 2 | If your widgets in the 'cards' list cause performance issues, you can choose to display more cards at a time to reduce how long the user waits for a card to appear | false diff --git a/example/lib/main.dart b/example/lib/main.dart index bdcbc00..0e6a524 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -76,13 +76,22 @@ class _ExamplePageState extends State { ); } - void _onSwipe( + bool _onSwipe( int? previousIndex, int? currentIndex, CardSwiperDirection direction, ) { + if (currentIndex?.isEven == true && direction == CardSwiperDirection.left || + currentIndex?.isOdd == true && direction == CardSwiperDirection.right) { + debugPrint( + 'the card $currentIndex was swiped to the: ${direction.name}; Oh, and also your action got canceled', + ); + return false; + } + debugPrint( 'the card $previousIndex was swiped to the ${direction.name}. Now the card $currentIndex is on top', ); + return true; } } diff --git a/lib/src/card_swiper.dart b/lib/src/card_swiper.dart index 23d3ccc..d563eaa 100644 --- a/lib/src/card_swiper.dart +++ b/lib/src/card_swiper.dart @@ -38,6 +38,9 @@ class CardSwiper extends StatefulWidget { final bool isDisabled; /// function that gets called with the new index and detected swipe direction when the user swiped or swipe is triggered by controller + /// + /// If [onSwipe] returns false, the swipe action will be canceled and the current card will remain on top of the stack. + /// Otherwise, if it returns true, the swipe action will be performed as expected. final CardSwiperOnSwipe? onSwipe; /// function that gets called when there is no widget left to be swiped away @@ -134,7 +137,9 @@ class _CardSwiperState extends State> double get _maxAngle => widget.maxAngle * (pi / 180); int? _currentIndex; + int? get _nextIndex => getValidIndexOffset(1); + bool get _canSwipe => _currentIndex != null && !widget.isDisabled; @override @@ -311,34 +316,55 @@ class _CardSwiperState extends State> } } + // handle the onSwipe methode as well as removing the current card from the + // stack if onSwipe does not return false + void _handleOnSwipe() { + setState(() { + if (_swipeType == SwipeType.swipe) { + final shouldCancelSwipe = widget.onSwipe + ?.call(_currentIndex, _nextIndex, detectedDirection) == + false; + + if (shouldCancelSwipe) { + return; + } + + final previousIndex = _currentIndex; + final isLastCard = _currentIndex == widget.cardsCount - 1; + + _currentIndex = _nextIndex; + widget.onSwipe?.call( + previousIndex, + _currentIndex, + detectedDirection, + ); + + if (isLastCard) { + widget.onEnd?.call(); + } + } + }); + } + + // reset the card animation + void _resetCardAnimation() { + setState(() { + _animationController.reset(); + _left = 0; + _top = 0; + _total = 0; + _angle = 0; + _scale = widget.scale; + _difference = 40; + _swipeType = SwipeType.none; + }); + } + //when the status of animation changes void _animationStatusListener(AnimationStatus status) { if (status == AnimationStatus.completed) { - setState(() { - if (_swipeType == SwipeType.swipe) { - final previousIndex = _currentIndex; - final isLastCard = _currentIndex == widget.cardsCount - 1; - - _currentIndex = _nextIndex; - widget.onSwipe?.call( - previousIndex, - _currentIndex, - detectedDirection, - ); - - if (isLastCard) { - widget.onEnd?.call(); - } - } - _animationController.reset(); - _left = 0; - _top = 0; - _total = 0; - _angle = 0; - _scale = widget.scale; - _difference = 40; - _swipeType = SwipeType.none; - }); + _handleOnSwipe(); + _resetCardAnimation(); } } diff --git a/lib/src/typedefs.dart b/lib/src/typedefs.dart index 9de9980..a2390ab 100644 --- a/lib/src/typedefs.dart +++ b/lib/src/typedefs.dart @@ -1,6 +1,6 @@ import 'package:flutter_card_swiper/src/enums.dart'; -typedef CardSwiperOnSwipe = void Function( +typedef CardSwiperOnSwipe = bool Function( int? previousIndex, int? currentIndex, CardSwiperDirection direction, diff --git a/pubspec.yaml b/pubspec.yaml index 35da6d3..77e6384 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_card_swiper description: This is a Tinder-like card swiper package. It allows you to swipe left, right, up, and down and define your own business logic for each direction. homepage: https://github.com/ricardodalarme/flutter_card_swiper issue_tracker: https://github.com/ricardodalarme/flutter_card_swiper/issues -version: 3.1.0 +version: 4.0.0 environment: sdk: ">=2.12.0 <3.0.0"