feat: onSwipe method can cancel the swipe (#9)

This commit is contained in:
Christian Richert 2023-03-24 02:11:42 +01:00 committed by GitHub
parent 37fcbe4ebe
commit 21ea7874ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 29 deletions

View File

@ -1,3 +1,10 @@
## [4.0.0]
- **BREAKING CHANGE**:
- CardSwipers onSwipe function now returns ```<bool>``` instead of ```<void>```. 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.

View File

@ -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

View File

@ -76,13 +76,22 @@ class _ExamplePageState extends State<Example> {
);
}
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;
}
}

View File

@ -38,6 +38,9 @@ class CardSwiper<T extends Widget> 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<T extends Widget> extends State<CardSwiper<T>>
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<T extends Widget> extends State<CardSwiper<T>>
}
}
// 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();
}
}

View File

@ -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,

View File

@ -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"