react-native-reanimated-carousel
react-native-reanimated-carousel copied to clipboard
Screen rotation issue
Hi!, Firstly, thank you for the library, it works very smoothly and has a great performance.
The only thing right now is this, I'm working on a tablet with screen rotation and when I rotate it the carousel item should be centered but it isn't, it's like the width wasn't been calculated again and therefore the slide position is wrong.
Could someone give me some tips or advice? I tried with the bare example and it is happening as well.
Thank you!
🔴
👨💻 I'm so busy recently, so I'm going away for a little while, but I'll come back by the end of this month.
♥️ Rest assured, I love this project, I will not give up.
2022.11.xx
Hi, You can put width to the "key" prop. The carousel will be re-generated when the width props change. I think this approach could work as a temporary workaround.
Hi, thanks for getting back to me so quickly.
I'll show you how I did it because I think there's some memory there. The width variable is passed expecting a re-render in the carousel and therefore centering the item, but it doesn't work. Here's my code;
const TabletCarousel = ({ ENTRIES }: TabletCarouselProps) => {
const { width, height } = useWindowDimensions();
const [activeSliderIndex, setActiveSliderIndex] = useState(0);
return (
<Carousel
loop={false}
width={width}
height={height * 0.75}
data={ENTRIES}
style={{ flex: 1 }}
renderItem={({ index }) => (
<View
style={{
backgroundColor: 'blue',
flex: 1,
}}
>
<Text
style={{
textAlign: 'center',
fontSize: 30,
}}
>
{index}
</Text>
</View>
)}
onSnapToItem={(index) => setActiveSliderIndex(index)}
/>
);
};
Once again, thank you and I'm looking forward to hearing from you.
Wondering about this same issue myself. Any progress on this? Especially for elements that take up the entire height and width of the screen; which imo should be a common use case.
@Danielcomes92 did you ever solve this issue?
Here's what I came up with. haven't really done any testing, but it works kinda. Only bug I see is screen flashes old layout for a second when rotating screen. Will update if I make further improvements
import React, {useState, useEffect} from 'react';
import {View, Dimensions, Text} from 'react-native';
import Carousel from 'react-native-reanimated-carousel';
function ResponsiveCarousel() {
const [screenDimensions, setScreenDimensions] = useState(
Dimensions.get('window'),
);
useEffect(() => {
const handleDimensionChange = newDimensions => {
setScreenDimensions(newDimensions.window);
};
Dimensions.addEventListener('change', handleDimensionChange);
return () => {
Dimensions.removeEventListener('change', handleDimensionChange);
};
}, []);
const data = [
{
id: 1,
text: 'Item 1',
},
{
id: 2,
text: 'Item 2',
},
// ...
];
return (
<View style={{flex: 1}}>
<Carousel
loop
width={screenDimensions.width}
height={screenDimensions.height}
data={data}
scrollAnimationDuration={1000}
onSnapToItem={index => console.log('current index:', index)}
renderItem={({index}) => (
<View
style={{
flex: 1,
borderWidth: 1,
justifyContent: 'center',
}}>
<Text style={{textAlign: 'center', fontSize: 30}}>
{data[index].text}
</Text>
</View>
)}
/>
</View>
);
}
export default ResponsiveCarousel;
this fixes the layout bug on rotation. Although I'm kinda new to react, so not sure if this is badly implemented or not. The carouselKey does a calculation on rotation and re-renders the carousel.
import React, {useState, useEffect} from 'react';
import {View, Dimensions, Text, ImageBackground, StatusBar} from 'react-native';
import Carousel from 'react-native-reanimated-carousel';
const carousel_0 = require('../assets/carousel_0.jpg');
const carousel_1 = require('../assets/carousel_1.jpg');
const carousel_2 = require('../assets/carousel_2.jpg');
function ResponsiveCarousel() {
const [screenDimensions, setScreenDimensions] = useState(
Dimensions.get('window'),
);
useEffect(() => {
const handleDimensionChange = ({window: newDimensions}) => {
setScreenDimensions(newDimensions);
};
Dimensions.addEventListener('change', handleDimensionChange);
return () => {
Dimensions.removeEventListener('change', handleDimensionChange);
};
}, []);
const data = [
{
id: 1,
text: 'Item 1',
image: carousel_0,
},
{
id: 2,
text: 'Item 2',
image: carousel_1,
},
{
id: 3,
text: 'Item 3',
image: carousel_2,
},
];
const carouselKey = `${screenDimensions.width}-${screenDimensions.height}`;
return (
<View style={{flex: 1}}>
<StatusBar hidden />
<Carousel
key={carouselKey}
loop
width={screenDimensions.width}
height={screenDimensions.height}
data={data.map(item => item.id)}
scrollAnimationDuration={1000}
onSnapToItem={index => console.log('current index:', index)}
renderItem={({index}) => (
<ImageBackground
source={data[index].image}
resizeMode="cover"
style={{
flex: 1,
justifyContent: 'center',
}}>
<Text style={{textAlign: 'center', fontSize: 30, color: 'white'}}>
{data[index].text}
</Text>
</ImageBackground>
)}
/>
</View>
);
}
export default ResponsiveCarousel;
Hi, I have the same issue here. Adding width to the key prop works kinda buggy. Is there any chance to have this problem fixed?
I was able to get the carousel to rerender and scroll to the active index with a mixture of useRef, useEffect, and key. Here's a very minimal code snippet:
const SomeCarousel = () => {
const { width, height } = useWindowDimensions();
const carouselRef = useRef(null);
const activeSlideIndex = useRef(0);
useEffect(() => {
carouselRef.current?.scrollTo({
index: activeSlideIndex.current,
animated: false,
})
}, [width])
return (
<Carousel
key={width}
ref={carouselRef}
onSnapToItem={(index) => { activeSlideIndex.current = index }}
// ...all your other props
/>
);
};