Open arlovip opened 7 months ago
The issue you're experiencing with autoPlay
not working on Android when used within a ScrollView is a known problem. A common workaround is to ensure the entire app is wrapped in GestureHandlerRootView
from react-native-gesture-handler
. This adjustment has helped others with similar issues:
import { Dimensions, ScrollView, Image, View } from "react-native";
import Carousel from "react-native-reanimated-carousel";
import { GestureHandlerRootView } from "react-native-gesture-handler";
export default function App(props) {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<ScrollView>
...
<Carousel
...
/>
...
</ScrollView>
</GestureHandlerRootView>
);
}
This solution is based on feedback from similar issues reported in the react-native-reanimated-carousel
repository. If this doesn't resolve the problem, consider manually controlling the autoPlay
feature based on the ScrollView's scroll activity. This involves pausing autoPlay
when scrolling starts and resuming it once scrolling stops. You can refer to the useAutoPlay
hook in the carousel's source code for guidance on implementing this behavior.
Try these approaches and see if they address the issue. If you encounter further difficulties or need more assistance, feel free to ask.
I also faced this issue.
My Carousel Component is inside Scrollview. (BannerImageSlider Component)
Problem 1 -> This slider stop between 2 items when scrolling initialize horizontally with a little bit of vertical scroll. Problem 2 -> After fixed Problem 1, another problem is auto play doesn't work if pan gesture of slider ended by cancel ( onCancelled props of panGestureHandlerProps)
Both Problem 1 and Problem 2 are solved.
This solution may help you :)
Problem 1
Problem 2
After fixed Problem 1 and Problem 2
// Solution
import React, { useRef, useState } from "react";
import { Dimensions, View } from "react-native";
import { Text } from "react-native-paper";
import Carousel from "react-native-reanimated-carousel";
export default function BannerImageSlider({
leftSpacing = 0,
rightSpacing = 0,
}) {
const width = Dimensions.get("window").width;
const containerWidth = width - leftSpacing - rightSpacing;
const sliderRef = useRef(null);
const absoluteProgressRef = useRef(0);
const isScrolling = useRef(false);
const [isFailedGesture, setIsFailedGesture] = useState(false);
return (
<View style={{ alignItems: "center" }}>
<Carousel
loop
ref={sliderRef}
width={containerWidth}
height={containerWidth / 2}
// Manually control autoPlay based on isFailedGesture (state)
autoPlay={!isFailedGesture}
data={[...Array(5)]}
scrollAnimationDuration={300}
autoPlayInterval={1000}
onSnapToItem={(index) => {}}
windowSize={20}
onProgressChange={(offsetProgress, absoluteProgress) => {
absoluteProgressRef.current = absoluteProgress;
}}
panGestureHandlerProps={{
activeOffsetX: [-10, 10],
// Fixed Problem 1 by comparing absoluteProgress (Ref) and
// currentIndex then manually scroll item
onCancelled: (event) => {
const currentIndex = sliderRef.current.getCurrentIndex();
const absoluteProgress = absoluteProgressRef.current;
if (absoluteProgress > currentIndex) {
sliderRef.current.next();
} else {
sliderRef.current.prev();
}
setIsFailedGesture(true);
},
}}
// Fixed Problem 2 by setting isFailedGesture (state) on scroll begin
// and on scroll end then manually control autoPlay value based on
// this state
onScrollBegin={() => setIsFailedGesture(false)}
onScrollEnd={() => setIsFailedGesture(false)}
snapEnabled={false}
pagingEnabled={true}
renderItem={({ item, index }) => (
<View
style={{
flex: 1,
justifyContent: "center",
}}
>
<Text variant="titleLarge" style={{ textAlign: "center" }}>
{index}
</Text>
</View>
)}
/>
</View>
);
}
@minhtet-ko Thank you for your answer. However, although the autoPlay
works after using your solution. But it introduces another problem that each time I put my finger on it and drag it, sliderRef.current.next()
is always triggered first. The expected result should be that the sliderRef.current.next()
and setIsFailedGesture(true)
are called after releasing my finger(Gesture). Anyway, thanks again.
Describe the bug
As described above,
autoPlay
settings does not work when scrolling up or down with touches oncarousel
in a scroll view on Android. It works well on iOS.To Reproduce Steps to reproduce the behavior:
react-native-reanimated-carousel
.Carousel
in a scroll view.autoPlay
andloop
astrue
.autoPlay
does not work on android, in other words, the autoPlay stops.Expected behavior
autoPlay
works well on Android even if when scrolling up or down.Screenshots
https://github.com/dohooo/react-native-reanimated-carousel/assets/22851821/664bde20-a7a2-415a-b032-bb42ddfcce92
Versions (please complete the following information):
Smartphone (please complete the following information):
Additional context
Codes