meliorence / react-native-snap-carousel

Swiper/carousel component for React Native featuring previews, multiple layouts, parallax images, performant handling of huge numbers of items, and more. Compatible with Android & iOS.
BSD 3-Clause "New" or "Revised" License
10.33k stars 2.28k forks source link

Scrolling inside carousel items #227

Closed mahomahoxd closed 6 years ago

mahomahoxd commented 6 years ago

Hi, I've been using the carousel for a while, it seems to be working all well. However, I had a question about having a list in an item of the carousel. For example, I have cards that I show, in which I have a list of children that I want to be able to scroll through in each card. Is it possible to do such a thing? I can imagine it has to do with certain thresholds and such, however I am a bit clueless on how to apply such a thing.

Thanks in advance!

bd-arc commented 6 years ago

Hi @mahomahoxd,

Well, do you want to be able to scroll your inner items in the same axis as the carousel one? Because that would be almost impossible to handle.

In a perpendicular axis, it should be possible. You could, for example, render a ScrollView inside each of your slides. However, be aware that React Native apparently has a lot of issues with nested ScrollView/VirtualizedList/FlatList. It's worth trying though ;-)

Do not hesitate to share some code on Snack.

darina-techery commented 6 years ago

I am now trying to implement slides as ScrollView with Image inside, because pinch-to-zoom functionality is required. However, I still cannot make it work. If I use a <View><Image/></View> construction, everything is rendered just fine, but with <ScrollView><Image/></ScrollView> images aren't loaded, and the loading indicator is endlessly circling in their place. I wonder if nested lists are to blame for that :(

bd-arc commented 6 years ago

@mahomahoxd @darina-techery I'll be happy to help you, but I just can't if you don't share on Snack an example that reproduces the issue...

mahomahoxd commented 6 years ago

@bd-arc, I'd gladly give you that, it just feels like if I do share a piece, you'd be missing a few things that I end up sending the entire project. I can try to type an example of what its similar to, in a way you could reproduce my issue. As for @darina-techery I might be able to help with that, the loading indicator only appears if you set a variable like this.state.isLoading for example in the isRefreshing prop of the carousel along with onRefresh. Its similar to how you use it with the flatlist. So if you have an infinite loading indicator, it might be that you don't set the variable back to false so it doesn't spin around anymore. What also can be is that you've done something wrong with the inside items so that it can't load properly (usually you see a yellow warning sign when that happens)

darina-techery commented 6 years ago

Hi @bd-arc! Unfortunately, I cannot now publish the whole app due to NDA, but I can provide the chunks of code illustrating the problem.

The image preview window is wrapped in Modal, so that it could be drawn over the Gallery screen. I should also mention that we use TypeScript.

Preview:

private renderPreview(): JSX.Element {
    const imageData: string[] = this.state.imageData.map(u => u.url).slice(0, 3); 
//without slice() images seem to be stuck on loading stage, even if initialNumToRender is provided, so it's a temporary workaround
    if (this.state.isPreviewShown) {

      return (
        <Modal isVisible={this.state.isPreviewShown} style={styles.modal} backdropOpacity={0.75}>
          <Carousel
            data={imageData}
            renderItem={this.renderImageCarousel}
            sliderWidth={sliderWidth}
            itemWidth={itemWidth}
          />
        </Modal>
      );

Carousel item (working example):

private renderImageCarousel(item: {item: string, index: number}): JSX.Element {
      return(
        <View style={styles.slide}>
          <Image source={{uri: item.item}} style={styles.slideInnerContainer}/>
        </View>
      );
  }

Carousel item (failing example, no images are loaded, only semi-transparent modal background is shown):

private renderImageCarousel(item: {item: string, index: number}): JSX.Element {
      return(
        <ScrollView style={styles.slide}>
          <Image source={{uri: item.item}} style={styles.slideInnerContainer}/>
        </ScrollView>
      );
  }

As you can see, the only difference is ScrollView VS View. No warnings shown. Can that help somehow?

bd-arc commented 6 years ago

@darina-techery I'll take a look at it as soon as I can, but it smells like a React Native bug... Have you tried with different versions of RN?

In the meantime, it would really help if you could post a minimal reproductible demo on Snack.

darina-techery commented 6 years ago

I somehow managed to find a working solution. My hypothesis is that it was style property of ScrollView and/or Image that caused the failure, but I cannot tell the exact difference between go and no-go solutions. I suspect that position: 'absolute' caused the problem, but I am not 100% sure of that.

Anyway, I can now confirm that it is possible to combine pagination from Carousel with pinch-to-zoom from ScrollView without rendering issues :)

bd-arc commented 6 years ago

Well, that's good news!

I know you can't share your exact code due to the NDA, but I'm positive that if want to avoid being assaulted with "How did you do that?" mails you should share an example someday ;-)

darina-techery commented 6 years ago

I will :)

This is not a completely bulletproof solution, however, it throws certain warnings at me, so I will have to investigate it in order not to mislead anyone.

bd-arc commented 6 years ago

I'm going to close the issue since the feature can apparently be implemented. Feel free to continue the discussion if needed.

Still hopping for a working example though ;-) I'll work on one myself, but I won't be able to do so for the next few weeks.

drtechie commented 5 years ago

Just putting it here. For me, the issue was TouchableOpacity.

Item.jsx

Before

<TouchableOpacity>
   <View>
        ...other Views...

       <ScrollableView>
           ... <Text> does not scroll
       </ScrollableView>
    <View>
</TouchableOpacity>

After

<View>
   <View>
        ...other Views...

       <ScrollableView>
           ... <Text> scrolls fine
       </ScrollableView>
    <View>
</View>
TitoSniberb commented 4 years ago

@bd-arc I know this post is really old but I have a similar problem and was hoping if there was a solution to it. Is it possible to use a horizontal Flatlist with scrolling inside the carousel? The carousel scrolling is also horizontal. Just to be clear if, I set the scrolling to vertical it works wonders.

bd-arc commented 4 years ago

@aldimirprincipal I've never had this use case, so hopefully others will be able to chime in. Still, those are the inherited props I would play with:

talaikis commented 3 years ago

All proposed solutions have no effect, as it is defined by RN documentation:

In order to bound the height of a ScrollView, either set the height of the view directly (discouraged) or make sure all parent views have bounded height.

So, the solution is to just wrap `ScrollView with fixed height parent View

AlkanV commented 2 years ago

i am having same issue @aldimirprincipal . i could not find any solution related with having a horizontal flatlist inside a horizontal carrousel. is there anyway for how can i render a horizontal flatlist inside horizontal carrousel?

thank you.

react06 commented 1 year ago

snapToInterval={ITEM_WIDTH} snapToAlignment="center" enableSnap={false} setting these Properties in the Carousel might work!