A simple React native Reusable Carousel component with Auto Play.Easy to add-on in any projects
Photo byNordWood ThemesonUnsplash
To follow this tutorial, Basic Knowledge of Reactnative and configurations required.You can directly grab source code from GitHub.
Finaloutput
Create basic project setup using Expo init or ReactNative Cli.This tutorial created with expo init
expo init BannerSlider
Once all Installation over , Run app using
Expo start
Make sure Initial setups run successfully in Android simulator / IOS emulator.
Now create Banner.js file inside src/components/Banner folder.(It's good practice to create components insider separate folder , so that can easily reuse it any project)
now create Banner.js , and copy paste below code in it.
import React, { useState, useEffect } from "react";
import {
View,
Text,
StyleSheet,
Dimensions,
FlatList,
Animated,
} from "react-native";
import Slide from "./Slide";
const { width, heigth } = Dimensions.get("window");
let flatList;
function infiniteScroll(dataList) {
const numberOfData = dataList.length;
let scrollValue = 0,
scrolled = 0;
setInterval(function () {
scrolled++;
if (scrolled < numberOfData) scrollValue = scrollValue + width;
else {
scrollValue = 0;
scrolled = 0;
}
this.flatList.scrollToOffset({ animated: true, offset: scrollValue });
}, 3000);
}
const Banner = ({ data }) => {
const scrollX = new Animated.Value(0);
let position = Animated.divide(scrollX, width);
const [dataList, setDataList] = useState(data);
useEffect(() => {
setDataList(data);
infiniteScroll(dataList);
});
if (data && data.length) {
return (
<View>
<FlatList
data={data}
ref={(flatList) => {
this.flatList = flatList;
}}
keyExtractor={(item, index) => "key" + index}
horizontal
pagingEnabled
scrollEnabled
snapToAlignment="center"
scrollEventThrottle={16}
decelerationRate={"fast"}
showsHorizontalScrollIndicator={false}
renderItem={({ item }) => {
return <Slide item={item} />;
}}
onScroll={Animated.event([
{ nativeEvent: { contentOffset: { x: scrollX } } },
])}
/>
<View style={styles.dotView}>
{data.map((_, i) => {
let opacity = position.interpolate({
inputRange: [i - 1, i, i + 1],
outputRange: [0.3, 1, 0.3],
extrapolate: "clamp",
});
return (
<Animated.View
key={i}
style={{
opacity,
height: 10,
width: 10,
backgroundColor: "#595959",
margin: 8,
borderRadius: 5,
}}
/>
);
})}
</View>
</View>
);
}
return null;
};
const styles = StyleSheet.create({
dotView: { flexDirection: "row", justifyContent: "center" },
});
export default Banner;
We need Slide.js which handles slides' looks and feel. Copy below code and paste it inside Slide.js.
import React from "react";
import { View, StyleSheet, Text, Image, Dimensions } from "react-native";
const { width, height } = Dimensions.get("window");
const Slide = ({ item }) => {
return (
<View style={styles.cardView}>
<Image style={styles.image} source={{ uri: item.url }} />
<View style={styles.textView}></View>
</View>
);
};
const styles = StyleSheet.create({
cardView: {
flex: 1,
width: width - 20,
height: height / 3,
backgroundColor: "white",
margin: 10,
borderRadius: 10,
shadowColor: "#000",
shadowOffset: { width: 0.5, height: 0.5 },
shadowOpacity: 0.5,
shadowRadius: 3,
elevation: 5,
},
textView: {
position: "absolute",
bottom: 10,
margin: 10,
left: 5,
},
image: {
width: width - 20,
height: height / 3,
borderRadius: 10,
},
itemTitle: {
color: "white",
fontSize: 22,
shadowColor: "#000",
shadowOffset: { width: 0.8, height: 0.8 },
shadowOpacity: 1,
shadowRadius: 3,
marginBottom: 5,
fontWeight: "bold",
elevation: 5,
},
itemDescription: {
color: "white",
fontSize: 12,
shadowColor: "#000",
shadowOffset: { width: 0.8, height: 0.8 },
shadowOpacity: 1,
shadowRadius: 3,
elevation: 5,
},
});
export default Slide;
Now use this Banner component anywhere with data. Here call it in App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Header from './src/components/Header';
import {BannerData} from './data/BannerData';
import Banner from './src/components/Banner/Banner';
export default function App() {
return (
<View style={styles.container}>
<Header/>
<Banner data={BannerData}/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
If you need dummy data to run this, you can get it from this DataLink