react-native-snap-carousel: snapToItem/snapToNext not working on Android devices when called from callbacks inside step

Is this a bug report, a feature request, or a question?

Bug report

Have you followed the required steps before opening a bug report?

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

Yes

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

Android only.

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

I think so.

Environment

Expo with v33 SDK

Expected Behavior

It should go to specified page or to the next.

Actual Behavior

On iOS device it is working fine, but on Android nothing happens.

Reproducible Demo

https://snack.expo.io/SJxF4GwlB

Steps to Reproduce

  1. Run on Android
  2. Try to snapToItem from inside single page view.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 17
  • Comments: 46 (9 by maintainers)

Most upvoted comments

setTimeout(() => this.carouselComponent.snapToNext(), 250)

adding timeout in the current version works for me 😃 less than 250 will not snap to next

This workaround setTimeout(() => this.carousel.snapToPrev(), 0) is still needed in "react-native-snap-carousel": "^3.8.2", 😦

The problem is here. When using snapToNext() or snapToPrev(), _snapToItem is triggered again with the old index

setTimeout(() => this.carouselComponent.snapToNext(), 250)

adding timeout in the current version works for me 😃 less than 250 will not snap to next

works for me! thanks 😃

I think we shouldn’t let this end here… We have just one workaround, but nothing concrete yet. Any update coming @bd-arc?

É uma pena que uma lib tão boa esteja abandonada! Até agora nada de soluções 😦

This solution setTimeout(() => this._carousel.snapToNext(), 0) and this one requestAnimationFrame(() => this._carousel.snapToPrev()) work for me, however the animation disappears in both cases (only on android). Any hint for this problem?

The only workaround that works for me is enabling momentum by setting props enableMomentum. I suspect that without this props, the _activeItem is not updated when calling snapToNext/snapToPrev.

source code

@Inovassist-dev I definitely agree that we need to get to the root of it.

The problem is that I need to know first and foremost if this is a bug introduced in 3.8.0 or something else. Hence my initial question.

But so far I’ve received contradictory answers…

"react-native-snap-carousel": "^3.7.5",
"react-native": "0.61.2",

requestAnimationFrame(() => this.carouselRef.snapToPrev()); requestAnimationFrame(() => this.carouselRef.snapToNext());

Is a work around if you’re sceptical when upgrading dependancies.

@bd-arc I know it is quite a really bad scenario because I looked also the releases notes of 0.60.5 and nothing seems to possibly interfere with thoses functions. I just tried again just now to be sure because I was also very surprised, and same situation : works on 0.59.4 and and not with 0.60.5 with exactly the same code and both 3.7.5.

The workaround with setTimeout works thought, but it is not usable since you can feel the delay and it feels really laggy then.

Just to give you more details on the code: I am calling snapToNext() or snapToPrev() directly from the item with TouchableWithoutFeedback. The touchable event is called and go without any problem to snapToNext() function (I checked with logs) but then nothing, it does not go to the next item. Also it does not work with snapToItem() too. I tried with and without Debug JS activated, and also with JS Dev Mode off.

I didn’t tried with iOS since I don’t have a Mac.

setTimeout(() => {
    this._carousel.snapToItem(-1);
    this._carousel.snapToItem(0);
}, 250);

I had issue to snap zero and it worked for me.

Update: Pull Request #648 fixes this! Are there any maintainers (@bd-arc maybe?) that can take a look to get this fix out? It appears that the issue was, when triggering the snapToNext() or snapToPrev() based on a button inside the carousel, the touch event was being seen the same as a touch & drag event, which triggered the snapToItem() function. The PR mentioned above differentiates the two, which fixes our problem

Just for a little further information (on the most recent 3.8.4 version): snapToNext() works if used outside of the carousel like this:

<Fragment>
  <Carousel
    ref={(c) => { this.carousel = c }}
    data={data}
    ...
  />
  <TouchableOpacity 
    style={{ backgroundColor: 'lime', position: 'absolute', bottom: 24, width: '90%', height: 42 }} 
    onPress={this.carousel.snapToNext} />
</Fragment>

But if you call this.carousel.snapToNext() from a carousel item it does not work (and must use the workarounds mentioned by others on this thread):

renderCarouselItem = ({ item, index }) => {
  return <SectionInput
    saveSection={() => { this.carousel.snapToNext(); this.saveSection() }}
    index={index}
    section={item}/>
}

This solution setTimeout(() => this._carousel.snapToNext(), 0) and this one requestAnimationFrame(() => this._carousel.snapToPrev()) work for me, however the animation disappears in both cases (only on android). Any hint for this problem?

The same, the animation disappears in both cases (only on android).

@QQizi any thoughts on how to fix?

Hi @kgorol,

Can you tell me if this works properly with version 3.7.5 of the plugin?