feature: display more cards behind the first one (#6)
This commit is contained in:
parent
6e40955758
commit
a8cbd3a110
|
|
@ -1,3 +1,7 @@
|
|||
## [2.1.0]
|
||||
|
||||
- Add option to display more cards at a time. Useful if the widgets you want in your cards take time to build (for example a network image or video): displaying more cards builds them in advance and makes a fast serie of swipes more fluid.
|
||||
|
||||
## [2.0.1]
|
||||
|
||||
- Fixes wrong item rendering.
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class Example extends StatelessWidget {
|
|||
| onSwipe | - | Called with the new index and detected swipe direction when the user swiped | 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
|
||||
|
||||
#### Controller
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class _ExamplePageState extends State<Example> {
|
|||
child: CardSwiper(
|
||||
controller: controller,
|
||||
cards: cards,
|
||||
numberOfCardsDisplayed: 3,
|
||||
onSwipe: _swipe,
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ class CardSwiper<T extends Widget> extends StatefulWidget {
|
|||
/// set to true if the stack should loop
|
||||
final bool isLoop;
|
||||
|
||||
/// here you can change the number of cards that are displayed at the same time
|
||||
final int numberOfCardsDisplayed;
|
||||
|
||||
const CardSwiper({
|
||||
Key? key,
|
||||
required this.cards,
|
||||
|
|
@ -68,6 +71,7 @@ class CardSwiper<T extends Widget> extends StatefulWidget {
|
|||
this.isHorizontalSwipingEnabled = true,
|
||||
this.isVerticalSwipingEnabled = true,
|
||||
this.isLoop = true,
|
||||
this.numberOfCardsDisplayed = 2,
|
||||
}) : assert(
|
||||
maxAngle >= 0 && maxAngle <= 360,
|
||||
'maxAngle must be between 0 and 360',
|
||||
|
|
@ -84,6 +88,10 @@ class CardSwiper<T extends Widget> extends StatefulWidget {
|
|||
scale >= 0 && scale <= 1,
|
||||
'scale must be between 0 and 1',
|
||||
),
|
||||
assert(
|
||||
numberOfCardsDisplayed >= 1 && numberOfCardsDisplayed <= cards.length,
|
||||
'you must display at least one card, and no more than the length of cards parameter',
|
||||
),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -116,7 +124,6 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
|||
|
||||
int get _currentIndex => _stack.length - 1;
|
||||
bool get _canSwipe => _stack.isNotEmpty && !widget.isDisabled;
|
||||
bool get _hasBackItem => _stack.length > 1 || widget.isLoop;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -152,10 +159,15 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
|||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (_hasBackItem) _backItem(constraints),
|
||||
if (_stack.isNotEmpty) _frontItem(constraints),
|
||||
],
|
||||
children: List.generate(nbOfCardsOnScreen(), (index) {
|
||||
if (index == 0) {
|
||||
return _frontItem(constraints);
|
||||
}
|
||||
if (index == 1) {
|
||||
return _secondItem(constraints);
|
||||
}
|
||||
return _backItem(constraints, index);
|
||||
}).reversed.toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -164,6 +176,19 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
|||
);
|
||||
}
|
||||
|
||||
///the number of cards that are built on the screen
|
||||
int nbOfCardsOnScreen() {
|
||||
return widget.isLoop
|
||||
? widget.numberOfCardsDisplayed
|
||||
: _stack.isNotEmpty
|
||||
? min(
|
||||
widget.numberOfCardsDisplayed,
|
||||
_stack.length,
|
||||
)
|
||||
: 0;
|
||||
}
|
||||
|
||||
/// The card shown at the front of the stack, that can be dragged and swipped
|
||||
Widget _frontItem(BoxConstraints constraints) {
|
||||
return Positioned(
|
||||
left: _left,
|
||||
|
|
@ -216,7 +241,9 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
|||
);
|
||||
}
|
||||
|
||||
Widget _backItem(BoxConstraints constraints) {
|
||||
/// the card that is just behind the _frontItem, only moves to take its place
|
||||
/// during a movement of _frontItem
|
||||
Widget _secondItem(BoxConstraints constraints) {
|
||||
return Positioned(
|
||||
top: _difference,
|
||||
left: 0,
|
||||
|
|
@ -227,6 +254,23 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
|||
child: _stack.length <= 1
|
||||
? widget.cards.last
|
||||
: _stack[_currentIndex - 1],
|
||||
//or: widget.cards[(_currentIndex - 1) % widget.cards.length] (same thing)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// if widget.numberOfCardsDisplayed > 2, those cards are built behind the
|
||||
/// _secondItem and can't move at all
|
||||
Widget _backItem(BoxConstraints constraints, int index) {
|
||||
return Positioned(
|
||||
top: 40,
|
||||
left: 0,
|
||||
child: Transform.scale(
|
||||
scale: widget.scale,
|
||||
child: ConstrainedBox(
|
||||
constraints: constraints,
|
||||
child: widget.cards[(_currentIndex - index) % widget.cards.length],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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: 2.0.1
|
||||
version: 2.1.0
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue