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.3k stars 2.28k forks source link

Android will not snap / snap callback when pulling towards index 0. #357

Open nlwiskus opened 6 years ago

nlwiskus commented 6 years ago

Is this a bug report or a feature request?

Bug Report

Have you read the guidelines regarding bug report?

Yes.

Have you read the documentation in its entirety?

Yes.

Have you made sure that your issue hasn't already been reported/solved?

Read through all open/closed issues using keywords 'android' and 'snap'

Is the bug specific to iOS or Android? Or can it be reproduced on both platforms?

Android

Is the bug reproductible in a production environment (not a debug one)?

Both in release and development builds, this issue comes up

Have you made sure that it wasn't a React Native bug?

I cannot find an issue that relates to my current issue.

Have you been able to reproduce the bug in [the provided example]

Yes. https://snack.expo.io/@nlwizkus/snapcarouselissue

Environment

Environment: React: ^16.2.0 React native: ^0.53.3 react-native-snap-carousel: ^3.7.2

Target Platform: Android (7.1)

Expected Behavior

Pulling past index 0 will snap to index 0, and the callback will fire.

video of ios: https://vimeo.com/user66774081/review/280244549/386e720eb6

Actual Behavior

When I pull down on the carousel, if I pull past the first item (index 0), the carousel refuses to snap. If I slightly towards index 1 afterwords, it will snap. If I pull slightly before (in-between 0 and 1) it will snap. Here is a video of what it is currently doing. There are animations in these examples but ignore that since I've tried this with those commented out. I've logged within the onSnap callback and it is not firing.

broken on android: https://vimeo.com/user66774081/review/280241289/9b73b34a23 (sorry, the mouse is in the middle of the screen since this was screen cast from a device. I'm doing the exact same motions as is shown in the ios video)

note: my issue isn't that it doesn't pull like it does in the ios, ie: going past the snap point on the beginning/end index. My issue is that the onSnapToItem doesn't get called when I pull past index 0 on android.

Reproducible Demo

    public render(): JSX.Element {
        return (
            <View style={styles.flexOne}>
                <Carousel
                    ref={(ref: any) => (this.carousel = ref)}
                    data={this.props.pickerOptions}
                    firstItem={START_INDEX} // 2
                    onSnapToItem={(index) => {
                        console.log('SNAP!', index);
                        this.props.onSelectRating(this.props.pickerOptions[index]);
                        this.setState({ activeCardIndex: index });
                    }}
                    enableSnap={true}
                    renderItem={this.renderItemForCarousel}
                    vertical={true}
                    itemHeight={(sliderHeight / this.props.pickerOptions.length) * 0.9}
                    sliderHeight={sliderHeight * 1.1} // ( * 1.1 fixes an issue with not snapping to last index)
                    inactiveSlideOpacity={0.5}
                    inactiveSlideScale={0.7}
                    slideStyle={styles.flexOne}
                    // scrollInterpolator={(i, p) => getScrollInterpolator(i, p)}
                    // slideInterpolatedStyle={(i, v) => getSlideInterpolatedStyle(i, v)}
                />
            </View>
        );
    }
    private renderItemForCarousel = (props: { item: Rating; index: number }) => {
        return (
            <TouchableOpacity onPress={() => this.pressedOption(props.index)} style={styles.container}>
                <Image style={styles.itemImage} source={ORDERED_PICKER_NUMBER_IMAGES[props.index]} />

                <Fade visible={props.index === this.state.activeCardIndex} style={styles.textContainer} duration={500}>
                    <Text style={styles.carouselText}>{this.state.activeCardIndex !== props.index ? '' : props.item.feeling}</Text>
                </Fade>
            </TouchableOpacity>
        );
    };
bd-arc commented 6 years ago

Hi @nlwiskus,

I fear this has to do with a strange vertical padding bug that appeared on Android in the latest versions of RN. I recommend that you take a look at #282 for more info.

Also, can you provide me with a Snack example that reproduces the issue? This would definitely help in finding a solution.

nlwiskus commented 6 years ago

@bd-arc Thank you for the reply! My assumption was some issue with top-padding, since adding more space to the bottom (sliderHeight=sliderHeight * 1.3) fixed my issue with snapping to the final index.

EDIT: Use this snap link, I created an expo account: https://snack.expo.io/@nlwizkus/snapcarouselissue

nlwiskus commented 6 years ago

@bd-arc did you get a chance to see the example? I haven't had any luck trying to find the root of the issue

bd-arc commented 6 years ago

Hi @nlwiskus,

I didn't have time to tackle it yet since I've been really busy lately. But rest assured that I didn't forget about the issue ;-)

I'm hoping on finding some time this week to try a few things out...

bd-arc commented 6 years ago

Hey @nlwiskus,

Sorry to hear that this prevents you from finishing your app. I should be able to take a look at the issue on Monday.

In the meantime, you can run a few tests to try and discover what's preventing this._onSnap() from being called in _onScroll().

Let's keep each other posted ;-)

bd-arc commented 6 years ago

@nlwiskus Just a quick update: I'm currently working on replacing the FlatList component altogether (see #250) because I'm fed up with the incredible amount of bugs it carries.

My hope is that it will help solving your issue.

Foskas commented 4 years ago

Any updates on this ? Also reproducing this on iOS even using scrollView

dohooo commented 2 years ago

Sorry, please allow me to advertise for my open source library! ~ I think this library react-native-reanimated-carousel will solve your problem. It is a high performance and very simple component, complete with React-Native reanimated 2