react-native-swiper
react-native-swiper copied to clipboard
Pagination dot is not moving on both android and ios
Version Which versions are you using:
- react-native-swiper 1.6.0
- react-native v0.63.4
Expected behaviour pagination dot should move on swiping to next item
Actual behaviour pagination dot are not moving on swiping to next item. Some time it works some time it stays stuck at 0 position.
How to reproduce it
<Swiper
height={Metrics.heightRatio(320)}
containerStyle={styles.swiper}
style={styles.swiper}
loop={false}
dotColor={Colors.primary.white}
dotStyle={{opacity: 0.4}}
activeDotColor={Colors.primary.white}
>
{data.map((item) => (
<ImageHandler
key={fast-${item.id}
}
source={{uri: item.path}}
style={styles.profileImg}
thumb={item.thumb}
/>
))}
</Swiper>
I'm noticing something similar to this, and in my case I'm pretty sure the dots stay stuck if the Swiper is not initially visible in the view. Anytime the Swiper is initially visible, it works fine. But in cases where it was made visible, the indexes don't work and the index change callbacks don't fire.
Ah, just kidding. It's because I was accidentally dynamically switching between a swiper with a single child to a swiper with many children. Seems like the number of children cannot / should not change dynamically. In my case because it started with a single child, the swiper continued to behave as if it had just a single child even though it now had many more.
so does the dot works fine with many childs?
It works fine with many children. It just needs to be initialized with that number of children.
I can confirm the behavior @chiubaka describes. The pagination dot is only stuck on the first one if the swiper was initiated with only one child. For my use case I need to change the content of the swiper dynamically. Does anyone have a workaround to make that work properly?
updateIndex = (offset, dir, cb) => { const state = this.state // Android ScrollView will not scrollTo certain offset when props change let index = state.index if (!this.internals.offset) // Android not setting this onLayout first? https://github.com/leecade/react-native-swiper/issues/582 this.internals.offset = {} const diff = offset[dir] - this.internals.offset[dir] const step = dir === 'x' ? state.width : state.height let loopJump = false
// added this line on library to make it work for dynamic childrens.
this.setState({index: offset.x / state.width});
Ah, just kidding. It's because I was accidentally dynamically switching between a swiper with a single child to a swiper with many children. Seems like the number of children cannot / should not change dynamically. In my case because it started with a single child, the swiper continued to behave as if it had just a single child even though it now had many more.
In my case I don't know how many slides will come from API. it could be 2 or it could be 50..! How can I initialized it??
I am fetching online data to fill swiper elements. Because the component has no data when it renders swiper doesn't work properly. Dots stack, loop doesn't work etc. In my project i show "announcements" in my swiper and my solution is rendering the swiper after i fetch "announcements":
{announcements !== null &&
<Swiper
autoplay
showsButtons
>
{announcements.map((item) => (
<TouchableOpacity
style={styles.eventImage}
onPress={() => handleEventSelected(item)} //Linking.openURL(item.target)
>
<Image
source={{ uri: item.banner.url }}
style={{ width: undefined, height: undefined, flex: 1 }}
resizeMode='cover'
/>
<Text
style={{
fontSize: 24,
color: 'wheat',
position: 'absolute',
top: 15,
left: 15,
textShadowColor: 'black',
textShadowRadius: 2
}}
>
{item.name}
</Text>
</TouchableOpacity>
))
}
</Swiper>
}
I am fetching online data to fill swiper elements. Because the component has no data when it renders swiper doesn't work properly. Dots stack, loop doesn't work etc. In my project i show "announcements" in my swiper and my solution is rendering the swiper after i fetch "announcements":
{announcements !== null && <Swiper autoplay showsButtons > {announcements.map((item) => ( <TouchableOpacity style={styles.eventImage} onPress={() => handleEventSelected(item)} //Linking.openURL(item.target) > <Image source={{ uri: item.banner.url }} style={{ width: undefined, height: undefined, flex: 1 }} resizeMode='cover' /> <Text style={{ fontSize: 24, color: 'wheat', position: 'absolute', top: 15, left: 15, textShadowColor: 'black', textShadowRadius: 2 }} > {item.name} </Text> </TouchableOpacity> )) } </Swiper> }
Try something like:
const [slides, setSlides] = useState(['', '', '']);
{ bannerList.length ? this.renderBanner(bannerList) : undefined }
if fetching online data to fill swiper elements, the render must after the got the data
so if render the Swiper, need make a judgement at first
中文翻译:
如果填充轮播图的内容,是在获取数据后。那么,渲染轮播图组件的时候,需要加个逻辑判断。不能是空数组map渲染出来,否则,指示器就不能滑动,永远激活在第一个。
paginationStyle={{position: 'absolute', bottom: 1}}