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]
|
## [2.0.1]
|
||||||
|
|
||||||
- Fixes wrong item rendering.
|
- 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
|
| 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
|
| 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
|
| 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
|
#### Controller
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ class _ExamplePageState extends State<Example> {
|
||||||
child: CardSwiper(
|
child: CardSwiper(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
cards: cards,
|
cards: cards,
|
||||||
|
numberOfCardsDisplayed: 3,
|
||||||
onSwipe: _swipe,
|
onSwipe: _swipe,
|
||||||
padding: const EdgeInsets.all(24.0),
|
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
|
/// set to true if the stack should loop
|
||||||
final bool isLoop;
|
final bool isLoop;
|
||||||
|
|
||||||
|
/// here you can change the number of cards that are displayed at the same time
|
||||||
|
final int numberOfCardsDisplayed;
|
||||||
|
|
||||||
const CardSwiper({
|
const CardSwiper({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.cards,
|
required this.cards,
|
||||||
|
|
@ -68,6 +71,7 @@ class CardSwiper<T extends Widget> extends StatefulWidget {
|
||||||
this.isHorizontalSwipingEnabled = true,
|
this.isHorizontalSwipingEnabled = true,
|
||||||
this.isVerticalSwipingEnabled = true,
|
this.isVerticalSwipingEnabled = true,
|
||||||
this.isLoop = true,
|
this.isLoop = true,
|
||||||
|
this.numberOfCardsDisplayed = 2,
|
||||||
}) : assert(
|
}) : assert(
|
||||||
maxAngle >= 0 && maxAngle <= 360,
|
maxAngle >= 0 && maxAngle <= 360,
|
||||||
'maxAngle must be between 0 and 360',
|
'maxAngle must be between 0 and 360',
|
||||||
|
|
@ -84,6 +88,10 @@ class CardSwiper<T extends Widget> extends StatefulWidget {
|
||||||
scale >= 0 && scale <= 1,
|
scale >= 0 && scale <= 1,
|
||||||
'scale must be between 0 and 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);
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -116,7 +124,6 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
||||||
|
|
||||||
int get _currentIndex => _stack.length - 1;
|
int get _currentIndex => _stack.length - 1;
|
||||||
bool get _canSwipe => _stack.isNotEmpty && !widget.isDisabled;
|
bool get _canSwipe => _stack.isNotEmpty && !widget.isDisabled;
|
||||||
bool get _hasBackItem => _stack.length > 1 || widget.isLoop;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -152,10 +159,15 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
||||||
return Stack(
|
return Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: List.generate(nbOfCardsOnScreen(), (index) {
|
||||||
if (_hasBackItem) _backItem(constraints),
|
if (index == 0) {
|
||||||
if (_stack.isNotEmpty) _frontItem(constraints),
|
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) {
|
Widget _frontItem(BoxConstraints constraints) {
|
||||||
return Positioned(
|
return Positioned(
|
||||||
left: _left,
|
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(
|
return Positioned(
|
||||||
top: _difference,
|
top: _difference,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
|
@ -227,6 +254,23 @@ class _CardSwiperState<T extends Widget> extends State<CardSwiper<T>>
|
||||||
child: _stack.length <= 1
|
child: _stack.length <= 1
|
||||||
? widget.cards.last
|
? widget.cards.last
|
||||||
: _stack[_currentIndex - 1],
|
: _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.
|
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
|
homepage: https://github.com/ricardodalarme/flutter_card_swiper
|
||||||
issue_tracker: https://github.com/ricardodalarme/flutter_card_swiper/issues
|
issue_tracker: https://github.com/ricardodalarme/flutter_card_swiper/issues
|
||||||
version: 2.0.1
|
version: 2.1.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue