lhandel / react-native-card-stack-swiper Goto Github PK
View Code? Open in Web Editor NEWTinder like react-native card stack swiper
License: MIT License
Tinder like react-native card stack swiper
License: MIT License
For some reason whenever there is only one Card Component inside CardStack, it is not rendered but rather "renderNoMoreCards" function is called.
Elevation is not supported for API < 25, please add zIndex on CardStack.js for android options,
Thank you
Hi, first of all, I would like to say this is good.
But when I add only one card in CardStack, there is an error of 'key of null'.
How can I solve this?
Thanks.
Can it be converted into kind of infinite scrolling. What is the performance with more than 100 cards ?
want to reload all cards from start. How I can achieve this ?
When I use the CardStack actions (like the example shows), the cards change without animations.
The .gif from the README shows an animation when the card is swiped from an action button.
What is missing to achieve that behaviour?
<TouchableOpacity onPress={ () => { this.swiper.swipeLeft() }}>
<Text>Left</Text>
</TouchableOpacity>
UPDATE
goBack* functions works as expected. The problem is in the four swipe* actions:
swipeBottom
swipeTop
swipeLeft
swipeRight
I'll check the differences in order to find a solution
Even after setting verticalSwipe={false}
on CardStack
component. The responder for vertical swipes is still the CardStack
component. The child Card
component is unable to take swipe input to enable a ScrollView
to work inside a Card
. Is there a solution to enabling scroll views in cards?
In the function onSwipedRight={(index) => alert("index is " + index)} the the index value is coming as undefined.
I tried it on both card and cardstack. for card it is always undefined while in card stack the function is called twice once with undefined and second time with the correct index.
Can you please tell me whats going wrong ??
Sometimes an invisible card appears, which I cannot swipe but I can give the like unlike button.
Hello,
Is there a way to go to the first card when card stack finished?
From
<CardStack style={styles.content} ref={swiper => { this.swiper = swiper }}>
To
const swiper = useRef(null);
<CardStack style={styles.content} ref={ swiper }>
index is undefined,maybe you forgot to add it to the method.Please fix it,thx:)
I want to update cards dynamically based on the response from an API that i've made to update the contents of the card. I've created a function that onSwiped will call the API and a request is sent to the API to fetch the data for the new card. This is what the function looks like.
fetchNextCardDetails = async () => {
const response = await fetch("127.0.0.1:5000/get-next-card-details")
const json = await response.json();
this.setState({ dataNextCard : json });
}
I understand that i need to update a key in the card component to be able to render a new card with the new data. Now since i am getting the data from an API, how should i update the key? Can the key be any random number or does it have to be in a sequence. Each card contains information about a new place, which is obtained from google's places API, which is then sent to the react-native app. Can i use the place_id that i get from Google as a key instead of numbers?
Fairly new with react-native needed help with my first app.
TypeError: Cannot read property 'key' of null
I have an async function I want to call from onSwiped but instead of being asynchronous it is blocking and the swipe animation is not finishing until the async function is done:
async onSwiped(indexCard){
/* some asynchronous operations */
}
<CardStack onSwiped={(indexCard) => {
this.onSwiped(indexCard)
}}
NOTE: Inside the async function I am setting some states
It would be better if there is a value which tells about the direction of swipe started, which could be either left or right. Based on that we can show some text or we can show some additional information.
Hello,
I Want to reload particular index object reload, I'm using setState for changing array data but card UI not rendering. So can you please provide me method or anyway, how to reload particular card?
In my app I have functionality to cart icon change color based on is_carted flag which I have managed in array and setState also change fine, but Card isn't rendering UI, so please give me an idea how to render the UI. I have already tested initDeck method but this method reloads all the cards again and we don't want back swappable card.
Hi ,
I Used this module but I have 5 cards and I need to show aa cards back of other but I tried giving marginLeft but its showing only 2 cards
How can I show all cards ?
Hi, I hope you are going well.
I am using this card-stack-swiper with data that are added dynamically.
But after load the next data, the card stack moves to the first card automatically.
For example, after swiping to the 10th card, the next 10 card-data is added dynamically via API.
In this case, the total number of cards is 20 but it moves to the very first card.
Does anybody have thoughts?
Thanks.
0.57.1
If any Touchable is included into a Card and stacked on top of one another, Every 2nd Card's Touchable will not work, but instead calls the Touchable of the Card below it.
E.g.
Top
______ <-- Card A
______ <-- Card B
______ <-- Card C
In this scenario, each card (A, B, C) has the same Touchable. At this point pressing the Touchable on the top will trigger onPress()
from Card A. Upon removing Card A from the Stack....
Top
______ <-- Card B
______ <-- Card C
Pressing the Touchable on the top at this point will trigger onPress()
from Card C, even though the expected behavior is to trigger onPress()
from Card B.
Relevant Issue: facebook/react-native#1076 (comment)
The behavior occurs due to positioning of CardA and CardB in CardStack.js
. Whichever card being placed below the other in the code will determine the which card's the Touchable is clickable.
In the current code, CardA will be rendered below CardB, allowing CardA's Touchable to be on the top, as shown below:
Top
______ <-- CardA
______ <-- CardB
Once a card is removed, CardB will be rendered on top whereas the next card will be rendered as the new CardA and be placed below CardB according to the zIndex
:
Top
______ <-- CardB
______ <-- CardA <-- Touchables take precedence
But since the code still renders CardA below CardB, CardA's Touchables will still take precedence over CardB's Touchables, irregardless of the zIndex
value of both cards,
Render CardA and CardB sequentially based on the topCard
variable in render()
. In doing so ensures that each Touchable at the top of the stack can be interacted with.
How do I access the card index of a particular card?
Android 7.0
IOS 14.1.4
Expo ^31.0.2
react 16.5.0
Consistent across both IOS and Android. If you update the stack from inside the CardStack the keyboard will be dismissed.
class Example extends Component {
constructor() {
super();
this.state = {
text: "0"
};
}
render() {
return(
<CardStack
style={{ flex: 1, alignItems: "center" }}
renderNoMoreCards={() => <View />}
>
<Card>
<View
style={{
width: Dimensions.get("window").width,
height: Dimensions.get("window").height
}}
>
<TextInput
onChangeText={score => this.state.setState(text: score)}
value={this.props.text}
/>
</View>
</Card>
<Card>
<View />
</Card>
</CardStack>
);
}
}
Hi,
I'm wondering if it's possible set a limit on directional swipe.
In my case i just wanna swipe right or down.
Nice library anyways!
When I try to add more cards dynamically, the stack won't update, so I need to give a "key" to the Swiper and update the key, which forces rerender.
I would rather add and remove children, but the Swiper won't notice such a change.
I want to pull more cards data from an API (10-20 cards at a time) so it is important for me.
The docs indicate that the arg passed to the callbacks for onSwipedLeft
and onSwipedRight
(for CardStack
) should receive the index in the stack of the card that was just swiped. From what I can tell this doesn't happen and there are no arguments passed at all.
Note that the example in this repo doesn't check for such an argument.
Using disable swiped (top, right, bottom or left) atributes only cancels calling onSwiped functions of that direction, but its still possible to swipe in that directions and card is removed from stack, next one is shown. Is there a way to fix this?
<CardStack
style={styles.content}
renderNoMoreCards={() => <Text style={{fontWeight:'700', fontSize:18, color:'gray'}}>No more cards :(</Text>}
ref={swiper => {
this.swiper = swiper
}}
disableLeftSwipe = {true}
>
<Card style={[styles.card, styles.card1]} onSwipedLeft={() => alert('onSwipedLeft')}><Text style={styles.label}>A</Text></Card>
<Card style={[styles.card, styles.card2]} onSwipedLeft={() => alert('onSwipedLeft')}><Text style={styles.label}>B</Text></Card>
<Card style={[styles.card, styles.card1]} onSwipedLeft={() => alert('onSwipedLeft')}><Text style={styles.label}>C</Text></Card>
<Card style={[styles.card, styles.card2]} onSwipedLeft={() => alert('onSwipedLeft')}><Text style={styles.label}>D</Text></Card>
<Card style={[styles.card, styles.card1]} onSwipedLeft={() => alert('onSwipedLeft')}><Text style={styles.label}>E</Text></Card>
</CardStack>
<CardStack loop={true}
will continuously loop with out giving knowledge of items were over... instead that, we need to re-load from starting...
i tried following way,
render =()=>{
var branches = [];
for (var i = 0; i < this.state.cardsList.length; i++) {
branches.push(
<Card key={i} style={[styles.cardItem]}>
<Image source={require('@images/plainbg.png')}/>
</Card>
}
return(
<CardStack loop={false} style={[{ alignItems: 'center' }]}
renderNoMoreCards={() =>
<TouchableOpacity onPress={this.reloadCards} style={{ marginTop: 50 }}>
<Text style={[styles.profileInput]}>Go Back!</Text>
</TouchableOpacity>}>
{branches}
</CardStack>
);
}
i tried to reload the render by setState, render method is reloading but not cards...
Hi, I want to disable gesture, but leave animation only for buttons swipe. How can I do that?
OnPress on card component is not working, here is my code.
<TouchableOpacity onPress={() => this.onPress(index)}>
<Text style={{
fontFamily: font.LatoBold,
fontSize: size.text_size_medium,
marginBottom: size.size_5,
color: color.gray_800
}}>
Click me
</Text>
</TouchableOpacity>
i want to get dy dx values or vx vy values when card is started to swipe
Hello @lhandel ,
I really appreciate your work, but I'm having one issue when I update some states it is NOT being updated inside card.
Can you please guide me here
For example, I have one state loading: true
in constructor,
In componentDidMount I set to loading: false
,
But this.state.loading never gets updated value and always returns (It is custom component - Which shows loader)
following is my code:
<CardStack
style={styles.cardstack}
verticalSwipe={false}
ref={(swiper) => {
this.swiper = swiper;
}}
renderNoMoreCards={() => (
<Text style={{fontWeight: '700', fontSize: 18, color: 'gray'}}>
No more cards :(
</Text>
)}
onSwiped={() => console.log('onSwiped')}
onSwipedLeft={() => console.log('onSwipedLeft')}>
<Card style={styles.card}>
{this.state.loading ? <Loader /> : null}
</Card>
</CardStack>
Here loader always keep loading even if state changes to false
When trying on Android devices (S8) I get a weird rotation cropping on card's child components and sometimes flickering of the card.
See video: http://www.screencast.com/t/F1G4yL2L1q6
As a workaround, for now, I'm disabling rotation on Android:
outputRotationRange={Platform.OS === 'ios' ? ['-15deg', '0deg', '15deg'] : ['-0deg', '0deg', '0deg']}
Any ideas on how to solve?
A function that recognizes if the movement is the right and the left would be to establish labels LIKE, NOPE ... And instead of rendering 2 cards, they were 3 or 4 even if the stack was not seen, so that the cache would of time to render an image.
I have looked at your code but I have no knowledge of animation ...
It seems there is something wrong in here:
ref={ swiper => {
this.swiper = swiper
}}
is it possible to add flip feature this library, trying to add flipview in card but its flipping, could please help me to solve the same
Hello, I used for a while react native deck swiper and with this library I had a cardIndex props and could save an index to start from there, in this library there is no similar props?
I also used a renderCard function, is the correct way to render all the items in the array with a map () and wrap the component in ?
And ... is it possible to add overlayLabels LIKE and NOPE so that the user knows which swipe address is correct?
Thank you for this library, it works very well and the animation is very smooth :)
Hello. I'm trying to figure out how to display the previous card when the user swipes from left to right. How can this be done?
I see the
goBackFromLeft | func
goBackFromRight | func
goBackFromBottom | func
goBackFromTop | func
but what exactly goes in these functions?
Hi ,
I Used this library i want to display text when card swipe like tinder show.
Help!!!!!!!!
Whenever I swipe a card, then use the goBackFrom...() function, it doesn't put the last swiped card on top. Instead, it puts the card that is at the bottom of the stack on top. Any fixes? Cheers!
here my code.
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image,
FlatList
} from 'react-native';
import CardStack, { Card } from 'react-native-card-stack-swiper';
const data = []
for (var i = 0; i < 10; i++) {
data.push({ key: i + 1 })
}
export default class App extends Component<{}> {
constructor(props){
super(props);
this.state = { dataCard: data };
}
renderItem(item) {
return (
<CardStack
style={styles.content}
renderNoMoreCards={() => <Text style={{ fontWeight: '700', fontSize: 18, color: 'gray' }}>No more cards :(</Text>}
ref={swiper => { this.swiper = swiper }}
onSwiped={() => console.log('onSwiped')}
onSwipedLeft={() => console.log('onSwipedLeft')}
>
<Card style={[styles.card, styles.card1]}>
<Text style={styles.label}>{item.key} a</Text>
</Card>
</CardStack>
)
}
render() {
return (
<View style={{ flex: 1 }}>
<FlatList
data={this.state.dataCard}
// data={[{key: 'a'}, {key: 'b'}]}
renderItem={({ item }) => this.renderItem(item)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#f2f2f2',
},
content: {
flex: 1,
// alignItems: 'center',
// justifyContent: 'center',
height: 500,
// width: 200,
borderWidth: 1,
borderColor: 'green'
},
card: {
width: 320,
height: 470,
// backgroundColor: '#FE474C',
borderRadius: 5,
shadowColor: 'rgba(0,0,0,0.5)',
shadowOffset: {
width: 0,
height: 1
},
shadowOpacity: 0.5,
borderWidth: 1
},
card1: {
// backgroundColor: '#FE474C',
},
card2: {
backgroundColor: '#FEB12C',
},
label: {
lineHeight: 400,
textAlign: 'center',
fontSize: 55,
fontFamily: 'System',
// color: '#ffffff',
backgroundColor: 'transparent',
},
footer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
buttonContainer: {
width: 220,
flexDirection: 'row',
justifyContent: 'space-between',
},
button: {
shadowColor: 'rgba(0,0,0,0.3)',
shadowOffset: {
width: 0,
height: 1
},
shadowOpacity: 0.5,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
zIndex: 0,
},
orange: {
width: 55,
height: 55,
borderWidth: 6,
borderColor: 'rgb(246,190,66)',
borderWidth: 4,
borderRadius: 55,
marginTop: -15
},
green: {
width: 75,
height: 75,
backgroundColor: '#fff',
borderRadius: 75,
borderWidth: 6,
borderColor: '#01df8a',
},
red: {
width: 75,
height: 75,
backgroundColor: '#fff',
borderRadius: 75,
borderWidth: 6,
borderColor: '#fd267d',
}
});
thank you !
I'm trying to implement an onPress handler for each card by adding a Touchable wrapper inside the Card element. It seems to work for the 1st card, but for the 2nd and 3rd cards, the onPress event of the 3rd card is called. Similarly, for the 4th and 5th card, the onPress event of the 4th card is called.
Seems like the cards are being rendered in pairs, and their order in the DOM is always the same regardless of one card being swiped away.
Is there any way to implement onPress properly?
how to call a function after all last card swiped.
I have simply added a TouchableHighlight as following:-
renderNoMoreCards={() => <TouchableHighlight onPress={() => this.onPressData()}
style={[styles.buttonContainerSubmit,styles.submitButton]}>
Submit
}
I want to directly call this.onPressData() without any button after swiping all the cards.
if am calling directly like this:-
renderNoMoreCards={this.onPressData() }
then i am not able to swipe the card. this function is executing first
how can I fix this???? prob please help me out
I'm not sure if I have found a bug or if I just don't know what I'm doing. I have a list of PlayingCard objects with values and methods, including getValue and getLink. I am trying to dynamically create cards inside of the CardStack with a map:
const cardSwipe = props.deck.map((card, index) => { <Card key={index}> <Image source={card.getLink()}></Image> </Card> });
...
<CardStack style={styles.cardImage} onSwipeEnd={handleCard} > {cardSwipe} </CardStack>
I get the following error in Expo:
TypeError: undefined is not an object (evaluating 'a[i].key'
If I replace {cardSwipe}
with a set of static cards like :
<Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[0].getLink()} /></Card> <Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[1].getLink()} /></Card> <Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[2].getLink()} /></Card> <Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[3].getLink()} /></Card> <Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[4].getLink()} /></Card> <Card style={styles.cardImage} ><Image style={styles.cardImage} source={props.deck[5].getLink()} /></Card>
Then everything works, but I can't figure out what is going wrong with the dynamic generation. Any help is appreciated.
Is it possible to load the cards from an array/list (one card generated for each element of the array) and later save them in another one (for example, disliked cards and liked cards)? Any tip on how to achieve it?
add a got to function which takes card number and animation direction. so, when we call that card all cards will be swiped to that index.
i tride to make other view overlay above cardstack but didn't worked
<View style={{position:'absolute',left:50,top:50}}>
JUST SOME RANDOM TEXT
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.