react-native-my-custom-slider
Version:
React Native custom slider library for seamless horizontal image sliding with snap-to-center functionality, indicators, and full customization support. Perfect for enhancing mobile UI experiences
109 lines (96 loc) • 3.17 kB
JavaScript
import React, { useRef, useState } from 'react';
import {
View,
FlatList,
Image,
Dimensions,
StyleSheet,
} from 'react-native';
const SCREEN_WIDTH = Dimensions.get('window').width;
const ImageSlider = ({ images }) => {
const [activeIndex, setActiveIndex] = useState(0);
const onViewableItemsChanged = ({ viewableItems }) => {
if (viewableItems && viewableItems.length > 0) {
setActiveIndex(viewableItems[0].index || 0);
}
};
const viewabilityConfigCallbackPairs = useRef([{ onViewableItemsChanged }]);
const flatListRef = useRef();
const handleScrollEnd = (event) => {
const offsetX = event.nativeEvent.contentOffset.x;
const newIndex = Math.round(offsetX / SCREEN_WIDTH);
setActiveIndex(newIndex);
if (flatListRef.current) {
flatListRef.current.scrollToIndex({ index: newIndex, animated: true });
}
};
const renderIndicator = () => {
return (
<View style={styles.indicatorContainer}>
{images.map((_, index) => (
<View
key={index}
style={[
styles.dot,
index === activeIndex ? styles.activeDot : null,
]}
/>
))}
</View>
);
};
return (
<View style={styles.container}>
<FlatList
ref={flatListRef}
data={images}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<Image
source={{ uri: item.image }}
style={styles.image}
resizeMode="contain"
/>
)}
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
viewabilityConfig={{
itemVisiblePercentThreshold: 50, // Adjust as needed
}}
snapToInterval={SCREEN_WIDTH}
decelerationRate="fast"
snapToAlignment="center"
onMomentumScrollEnd={handleScrollEnd}
/>
{images.length > 1 ? renderIndicator() : null}
</View>
);
};
const styles = StyleSheet.create({
container: {
//flex: 1,
},
image: {
marginTop: 10,
width: SCREEN_WIDTH,
height: 315,
},
indicatorContainer: {
marginTop:10,
alignSelf: 'center',
flexDirection: 'row',
},
dot: {
width: 6,
height: 6,
borderRadius: 3,
backgroundColor: 'grey',
marginHorizontal: 3,
},
activeDot: {
backgroundColor: '#43A6C6',
},
});
export default ImageSlider;