alexbrillant / react-native-deck-swiper

tinder like react-native deck swiper
ISC License
1.56k stars 465 forks source link

[Feature Request] Infinite swiping with lazy loading #7

Closed BuildWithLal closed 7 years ago

BuildWithLal commented 7 years ago

I am trying to call Swiper with a list which has only single item but it displays it 2 times. not sure what i am doing wrong or havn't understand it well.

const cards = [ { id: 4, videoFile: '/data/assets/vid.mp4' , name: 'Sovereign Light Cafe'} ]

renderContent(video) {
    return (
      <View style={{ flex: 1 }} >
          <Video source={{ uri: video.videoFile }} />
       </View>
    );
  }

<Swiper
           cards={cards}
           renderCard={this.renderContent}
           onSwipedTop={this.swipedTop}
           onSwipedBottom={this.swipedBottom}
           infinite
           style={{ width, height }}
/>

when i first load it, there are 2 videos playing on the top of each other. screenshot_2017-05-07-23-56-29

alexbrillant commented 7 years ago

What react native version are you using? I cannot reproduce with 0.43.3 I tried having only one item in the cards props, and the second view wasn't being rendered as expected.

alexbrillant commented 7 years ago

I found the solution : set the infinite props to false. Also, make sure that the value of the cards props is not an empty array.

The infinite prop makes swiping infinite when set the true.
It is the default value so you can just remove it like this :

<Swiper
     cards={cards}
     renderCard={this.renderContent}
     onSwipedTop={this.swipedTop}
     onSwipedBottom={this.swipedBottom}
     style={{ width, height }} />

@lalzada Is this good now?

BuildWithLal commented 7 years ago

Thanks for quick support..

Yes.. removing infinite did the trick but the actual problem is still there..

I am replacing that single item in list when user swipe (onSwipedTop and onSwipedBottom). The main purpose is to load next video when user swipe on screen... Lazy loaded videos

if i have single item in list at the start and i remove the infinite then after swipe there is nothing left on screen.

OR

i am keeping that list empty and render my next video inside renderCard() function when user swipe but keeping infinite in this scenario is still creating the same problem.. duplicating same video.

this scenario is best fit for onSwipe() instead of onSwiped() so one could change the cards list just before swipe. so after one item is swiped there would be next item in list..

BuildWithLal commented 7 years ago

ohh i see that the next video is playing when i swipe on screen but its not showing on screen actually.. Don't know the the problem is exactly...

alexbrillant commented 7 years ago

Here is an exemple of inifinite swiping with lazy loading.

As you can see, you can keep the cards in the state of the component containing the Swiper, and add elements on the onSwiped events... @lalzada let me know if you have any questions.

import React, { Component } from "react"
import Swiper from "react-native-deck-swiper"
import { StyleSheet, View, Text, Image, Button } from "react-native"

export default class Exemple extends Component {
  constructor(props) {
    super(props)
    this.state = {
      cards: [1, 2],
      swipedAllCards: false,
      isSwipingBack: false,
      cardIndex: 0
    }
  }

  renderCard = (card) => {
    return (
      <View style={styles.card}>
        <Text style={styles.text}>{card}</Text>
      </View>
    )
  }

  onSwiped = () => {
    const {cards} = this.state
    const newCardNumber = cards[cards.length - 1] + 1
    this.setState({
      cards: [...this.state.cards, newCardNumber]
    })
  }

  render() {
    return (
      <View style={styles.container}>
        <Swiper
          ref={swiper => {
            this.swiper = swiper
          }}
          onSwiped={this.onSwiped}
          cards={this.state.cards}
          cardIndex={this.state.cardIndex}
          cardVerticalMargin={80}
          renderCard={this.renderCard} />
      </View>
    )
  }
}

const styles = StyleSheet.create({
  box1: {
    flex: 1
  },
  container: {
    flex: 1,
    backgroundColor: "#F5FCFF"
  },
  card: {
    flex: 1,
    borderRadius: 4,
    borderWidth: 2,
    borderColor: "#E8E8E8",
    justifyContent: "center",
    backgroundColor: "white"
  },
  text: {
    textAlign: "center",
    fontSize: 50,
    backgroundColor: "transparent"
  },
  done: {
    textAlign: "center",
    fontSize: 30,
    color: "white",
    backgroundColor: "transparent"
  }
}
safciplak commented 4 years ago

newCardNumber

i tried but no way. still i didn't add new card. could you please to me?

hbarylskyi commented 4 years ago

Example above should work with #285. @safciplak you can try that.