This tutorial is the fifth part of our React Native Travel Article App UI clone series. In the , we successfully implemented the Recommendation Section on our List Screen. This tutorial is the continuation of the same tutorial from where we left off in the last part. So, it is recommended to go through the previous parts in order to get the knowledge and insight into the overall project. previous part The motivation for this tutorial series came from the React Native App Templates that consists of a wide variety of beautiful templates written in React Native and powered by universal features and design. The templates enable us to implement our own apps and even help us get started with our own startups. And, this fifth part is also the continuation of the same coding implementations and designs from the Youtube video tutorial by for the Travel Article App UI clone. The video tutorial delivers the overall tutorial using fast coding which may be difficult to grasp for any developer especially the beginners. Hence, this article tutorial provides a step by step implementation which will be easier to understand and implement. So, the learners can relax and take their time to implement the UI. React UI Kit Overview In this fifth part of this tutorial series, we are going to implement the Animated Delimeter dots of the Destinations section. The idea is to make the delimiter dots active in the animated fashion while scrolling the Destination section cards. After we complete this, we are going to store our color and size style properties in a different file. Then, we are going to use the style properties from that file to style the components in our List Screen. This will make our code clean and organized for better understanding. So, let us begin!! Making Some Configuration in FlatList of Destinations section Here, we are going to add an additional prop to the FlatList component of the Destinations section. The prop we are going to add is decelerationRate. This decelerationRate prop is a floating-point number that determines how quickly the scroll view decelerates after the user lifts their finger. Now, we are going to add this prop to our FlatList component as shown in the code snippet below: <View style={[ styles.flex, styles.column, styles.destinations]}> `${item.id}`} renderItem = {({item}) => this.renderDestination(item)} /> {this.renderDots()} < = = = = // = ' ' }} // = = )=> FlatList horizontal pagingEnabled scrollEnabled showsHorizontalScrollIndicator {false} scrollEventThrottle {16} snapToAlignment "center" decelerationRate {0} style {{ overflow : visible In IOS platform data {destinations} keyExtractor {(item, index </ > View Adding Animation to Delimiter Dots In this step, we are going to add the Animation to our Delimiter Dots in our Destinations section. For that, we need to import the Animated component from the react-native package as shown in the code snippet below: { StyleSheet, Platform, Text, View, ScrollView, Dimensions, ImageBackground, Image, FlatList, TouchableOpacity, Animated } ; import from 'react-native' Now, we need to define a variable called that is initialized to Animated value. This variable will store our animation value for horizontal animation. In order to do this, we need to use the code from the following code snippet: scrollX { scrollX = Animated.Value( ); export default . class List extends React Component new 0 Here, the Animated.Value configuration enables us to bind to style properties or other props and can be interpolated as well. Now, we need to configure this value into the event of the component of function as shown in the code snippet below: scrollX onScroll FlatList renderDestinations() <FlatList horizontal pagingEnabled scrollEnabled showsHorizontalScrollIndicator = { } scrollEventThrottle = { } snapToAlignment = decelerationRate={ } onScroll={Animated.event([{ : { : { : .scrollX }} }])} data = {destinations} keyExtractor = {(item, index)=> } renderItem = {({item}) => .renderDestination(item)} /> false 16 "center" 0 // style={{ overflow : 'visible' }} //In IOS platform nativeEvent contentOffset x this ` ` ${item.id} this Here, we have used the event function of the Animated component which takes the as a parameter. Then, we have defined the value according to the variable inside the nativeEvent config. nativeEvent contentOffset scrollX Configuring Animation in Delimiter dots in accordance with the scrolling FlatList Here, we are going to add animation to the Delimiter dots which will depend on the event of the . For that, we need to first initialize the dot position using the divide function of the component. The divide function creates a new Animated value composed by dividing the first Animated value by the second Animated value. And, its use is shown in the code snippet below: onScroll FlatList Animated dotPosition = Animated.divide( .scrollX, width); const this Now, we are going to make some configuration in the function in order to animation properties to the dots. For that, we need to use the code from the code snippet below: renderDots() Delimiter renderDots() { dotPosition = Animated.divide( .scrollX, width); ( <Animated.View key={`step-${item.id}`} style={[styles.dots, styles.activeDot, { borderWidth: borderWidth } ]} /> ) })} </View> const this return {destinations.map((item, index) => { const borderWidth = dotPosition.interpolate({ inputRange: [index -1, index, index + 1], outputRange: [0, 2.5, 0], extrapolate: 'clamp' }); return ( < = , , { ' ', ' ', } ]}> View style {[ styles.flex styles.row justifyContent: center alignItems: center marginTop: 10 ) } Here, we have defined a constant called which is initialized to the function of the constant initlized to Animated.divide. The function takes , and extrapolate as parameter values. borderWidth interpolate() dotPosition interpolate() inputRange outputRange The function permits input ranges to map to different output ranges. Then, we have also added component to our component with style property. interpolate() Animated View borderWidth Hence, we will get the following result in our emulator screen: As we can see, we have successfully added beautiful animation to the Delimiter dots as we scroll the Destination section card in the Destination section. The animation is very smooth and works well with the scrolling transition. Configuring Style properties Here, we are going to configure the style properties from a separate file. Then, we will style our List Screen components according to the style properties in that file. Storing Style Properties in Different File In this step, we are going to store our size and color properties used very commonly on the List screen to a different file called . This will make things easier for us to assign styles to different components. Now, we need to create a file called in our main project folder as shown in the code snippet below: ‘theme.js’ ‘theme.js’ As we can see, we have got the file. Now, in the theme.js file we need to define our colors and sizes properties as shown in the code snippet below: ‘theme.js’ colors = { : , : , : , : , : , }; sizes = { : , : , : , : , : , : , }; { colors, sizes, }; const black '#000' white '#FFF' gray '#DCE0E9' caption '#BCCCD4' active '#007BFA' const base 16 font 14 padding 36 margin 36 title 24 radius 12 export Here, we have defined the color and size style properties in the colors and sizes constant variables that are then exported. Integrating Color and Size style properties based on theme.js file Since we have defined some common style properties in the theme.js file, here we are going to import the styles from file and integrate them into our component inline styles as well as the styles in the component. But first, we need to import the file into our file as shown in the code snippet below: theme.js StyleSheet theme.js List.js * theme ; import as from '../theme' Now, we are going to change the color and size style properties in accordance with the pre-defined styles from the theme.js file. Changing color style properties in accordance with theme.js Here, we are going to change the color style properties in the file with the colors variable from the theme.js file. All the changes made to the style properties in the component is provided in the code snippet below: List.js StyleSheet header: { : theme.colors.white, : , : , : , : , : , }, : { : , : , : , : , : , left : , : , : theme.colors.white, }, : { : (width - ( * )) / , : , : theme.colors.white, : , : , : * , }, : { : * , : theme.colors.white }, : { : , : theme.colors.white, : }, : { : theme.colors.black, : { : , : , }, : , : , : , }, : { : , : , : , : , : , : theme.colors.gray, : , }, : { : , : , : , : theme.colors.active, } backgroundColor paddingHorizontal 36 paddingTop 48 paddingBottom 24 justifyContent 'space-between' alignItems 'center' destinationInfo position 'absolute' borderRadius 12 paddingHorizontal 36 paddingVertical 16 bottom 20 //In iOS platform, bottom : -36 36 right 36 backgroundColor recommendation width 36 2 2 marginHorizontal 8 backgroundColor overflow 'hidden' borderRadius 12 marginVertical 36 0.5 recommendationTemp fontSize 14 1.25 color rating fontSize 28 color fontWeight 'bold' shadow shadowColor shadowOffset width 0 height 6 shadowOpacity 0.05 shadowRadius 10 elevation 5 dots width 10 height 10 borderWidth 2.5 borderRadius 5 marginHorizontal 6 backgroundColor borderColor 'transparent' activeDot width 12.5 height 12.5 borderRadius 6.25 borderColor Now, we have some inline styles as well bound to the components in the different templating methods. We need to change them in accordance with colors variable as well. All overall code with changes is provided in the code snippets below: In the header config of the object: navigationOptions <Text style={{ : theme.colors.caption}}>Search place< color for /Text> For the function: renderDestination() renderDestination(item){ ( <View style={[styles.row, {justifyContent: 'space-between'}]}> <View style={{flex : 0}}> <Image source={{uri: item.user.avatar}} style={styles.avatar}/> </View> <View style={[styles.column, {flex : 2, paddingHorizontal : 18}]}> <Text style={{color : theme.colors.white, fontWeight : 'bold'}}>{item.user.name}</Text> <Text style={{color : theme.colors.white}}>{item.location}</Text> </View> <View style={{flex : 0, justifyContent : 'center', alignItems : 'flex-end'}}> <Text style={styles.rating}>{item.rating}</Text> </View> </View> <View style={[styles.column, styles.destinationInfo, styles.shadow]}> <Text style={{ fontSize: 24, fontWeight: '500', paddingBottom: 8, }}> {item.title} </Text> <View style={[ styles.row, { justifyContent: 'space-between', alignItems: 'flex-end'}]}> <Text style={{ color : theme.colors.caption}}> {item.description.split('').slice(0, 50)}... </Text> </View> </View> </ImageBackground> return < = , ]} = }} = }} > ImageBackground style {[styles.flex, styles.destination styles.shadow imageStyle {{borderRadius : 12 source {{uri : item.preview ) } In the function renderRecommended() <TouchableOpacity activeOpacity={ }> < 0.5 More < = }}> Text style {{ color: theme.colors.caption </ > Text /TouchableOpacity> For the function: renderRecommendations() <View style={[styles.flex, styles.column, styles.shadow, { : , : / }]}> <Text style={{ : theme.colors.caption}}>{item.location}< Text> < justifyContent 'space-evenly' padding 36 2 {item.title} < = * , ' ', / , }}> Text style {{ fontSize: 16 1.25 fontWeight: 500 paddingBottom: 36 4.5 </ > Text color /Text> <View style={[ styles.row, { alignItems: 'center', justifyContent: 'space-between', marginTop: 36 } ]}> <Text style={{ color: theme.colors.active }}>{item.rating}</ </ > View /View> Changing size properties in accordance with theme.js Here, we are going to change the size style properties in the file with the sizes variable from the theme.js file. All the changes made to the style properties in the component is provided in the code snippet below: List.js StyleSheet header: { : theme.colors.white, : theme.sizes.padding, : theme.sizes.padding * , : theme.sizes.padding * , : , : , }, : { : , : , : , }, : { : width - (theme.sizes.padding * ), : width * , : theme.sizes.margin, : theme.sizes.padding, : , : theme.sizes.radius }, : { : , : theme.sizes.radius, : theme.sizes.padding, : , : , left : theme.sizes.padding, : theme.sizes.padding, : theme.colors.white, }, : { : , : , : theme.sizes.padding, }, : { : (width - (theme.sizes.padding * )) / , : , : theme.colors.white, : , : theme.sizes.radius, : theme.sizes.margin * , }, : { : , : theme.sizes.radius, : theme.sizes.radius, }, : { : , : , : theme.sizes.padding / , : , : , : , : , }, : { : * , : theme.colors.white }, : { : (width - (theme.sizes.padding* )) / , : (width - (theme.sizes.padding * )) / , }, :{ : theme.sizes.padding, : theme.sizes.padding, : theme.sizes.padding / }, : { : theme.sizes.font * , : theme.colors.white, : }, backgroundColor paddingHorizontal paddingTop 1.33 paddingBottom 0.66 justifyContent 'space-between' alignItems 'center' destinations flex 2 justifyContent 'space-between' paddingBottom 30 destination width 2 height 0.66 marginHorizontal paddingHorizontal paddingVertical 20 borderRadius destinationInfo position 'absolute' borderRadius paddingHorizontal paddingVertical 16 bottom 20 //In iOS platform, bottom : -36 right backgroundColor recommendedHeader justifyContent 'space-between' alignItems 'flex-end' paddingHorizontal recommendation width 2 2 marginHorizontal 8 backgroundColor overflow 'hidden' borderRadius marginVertical 0.5 recommendationHeader overflow 'hidden' borderTopRightRadius borderTopLeftRadius recommendationOptions alignItems 'center' justifyContent 'space-between' padding 2 position 'absolute' top 0 left 0 right 0 recommendationTemp fontSize 14 1.25 color recommendationImage width 2 2 height 2 2 avatar width height borderRadius 2 rating fontSize 2 color fontWeight 'bold' Now, we have some inline styles as well bound to the components in the different templating methods. We need to change them in accordance with sizes variable as well. All overall code with changes is provided in the code snippets below: In the header config of the object: navigationOptions <Text style={{ : theme.sizes.font * }}>Destination< fontSize 2 /Text> For the function: renderDots() <View style={[ styles.flex, styles.row, { : , : , : Platform.OS === ? theme.sizes.padding * : } ]} > ................. justifyContent 'center' alignItems 'center' marginTop 'ios' 2 48 In the function: renderDestinations() <ImageBackground style={[styles.flex, styles.destination, styles.shadow]} imageStyle = {{ : theme.sizes.radius}} source= {{ : item.preview}} > <View style={{flex : 0}}> <Image source={{uri: item.user.avatar}} style={styles.avatar}/> </View> <View style={[styles.column, {flex : 2, paddingHorizontal : theme.sizes.padding / 2}]}> <Text style={{color : theme.colors.white, fontWeight : 'bold'}}>{item.user.name}</Text> <Text style={{color : theme.colors.white}}>{item.location}</Text> </View> <View style={{flex : 0, justifyContent : 'center', alignItems : 'flex-end'}}> <Text style={styles.rating}>{item.rating}</Text> </View> </View> <View style={[styles.column, styles.destinationInfo, styles.shadow]}> <Text style={{ fontSize: theme.sizes.title, fontWeight: '500', paddingBottom: 8, }}> {item.title} </Text> <View style={[ styles.row, { justifyContent: 'space-between', alignItems: 'flex-end'}]}> <Text style={{ color : theme.colors.caption}}> {item.description.split('').slice(0, 50)}... </Text> </View> </View> borderRadius uri < = { ' '}]}> View style {[styles.row, justifyContent: space-between </ > ImageBackground For function: renderRecommended() <Text style={{ : theme.sizes.font * }}>Recommended< fontSize 1.4 /Text> In function renderRecommendation() <View style={[styles.flex, styles.column, styles.recommendation, styles.shadow, index === ? { : theme.sizes.margin } : , isLastItem ? { : theme.sizes.margin / } : , ]} > <Image style={[styles.recommendationImage]} source={{ uri: item.preview }} /> <View style={[ styles.flex, styles.row, styles.recommendationOptions ]}> <Text style={styles.recommendationTemp}> {item.temperature}℃ </Text> </View> </View> <View style={[styles.flex, styles.column, styles.shadow, { justifyContent: 'space-evenly', padding: theme.sizes.padding / 2 }]}> <Text style={{ fontSize: theme.sizes.font * 1.25, fontWeight: '500', paddingBottom: theme.sizes.padding / 4.5, }}>{item.title}</Text> <Text style={{ color: theme.colors.caption}}>{item.location}</Text> <View style={[ styles.row, { alignItems: 'center', justifyContent: 'space-between', marginTop: theme.sizes.margin } ]}> <Text style={{ color: theme.colors.active }}>{item.rating}</Text> </View> </View> 0 marginLeft null marginRight 2 null < = ]}> View style {[styles.flex, styles.recommendationHeader </ > View Hence, after everything is organized, we will get the same result as before which is shown in the following emulator simulation: As we can see, the result is the same as before with all the codes organized. Now, we will be able to configure style properties easily in the upcoming parts of this tutorial series. With this, we have come to the end of this part of the tutorial series. Finally, we have successfully implemented the Animated Delimiter dots in the section of our screen. Destinations List Conclusion This tutorial is the fifth part of the React Native Travel Article App UI clone tutorial series. In this part, we continued from where we left off in the fourth part of this tutorial series. In this part of the tutorial, we got stepwise guidance on how to add beautiful active style animation to the of the section. Hence, we made the active animation of in accordance with the scrolling of the section cards. Then, we also organized our inline styles and styles in the component to make code standard and clear. Hence, we can now style our components more easily in the upcoming parts of this tutorial series. Delimiter dots Destinations Delimeter dots Destination StyleSheet In the next part of this tutorial series, we are going to add the icons to our List screen as well as the rating stars to our Recommendation Info cards.