I am a beginner in react native. I am trying to place an add button above each item of flatList but it is displayed on items of first column.
This is my FlastList code
<FlatList
data={prodListPerCategory}
keyExtractor={(prd) => (prd.id)}
renderItem={({ item }) => (
<ProductCard
key={item.id}
image={item.images[0].src}
title={item.name}
price={item.price}
onPress={() => navigation.navigate('SearchedProduct', item)}
/>
)}
numColumns={3}
/>
This is my ProductCard component code:
const ProductCard = ({ image, title, price, onPress }) => {
return (
<>
<TouchableOpacity style={styles.addBtn} onPress={()=>{alert('Item Added')}}>
<Image source={require('../Assets/PNGs/Products/add.png')} resizeMode={'contain'} style={{width:15, height:15}} />
</TouchableOpacity>
<TouchableOpacity style={styles.container} onPress={onPress}>
<View style={styles.card}>
<Image source={{uri:`${image}`}} resizeMode='stretch' style={{ width: '80%', height: '80%' }} />
</View>
<View style={styles.titleView}>
<Text numberOfLines={2} style={styles.titleStyle}>{title}</Text>
<Text style={styles.priceText}>${price}</Text>
</View>
</TouchableOpacity>
</>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'space-between',
width: width * (25 / 100),
height: height * (22 / 100),
marginHorizontal: '3.5%',
marginBottom: '2%',
},
card: {
height: '60%',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 5,
borderRadius: 5,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
backgroundColor: 'white',
},
titleView: {
flex: 0.9,
alignItems: 'center',
},
titleStyle: {
width: '100%',
fontSize: 12,
textAlign: 'center',
color: '#6E1033',
fontWeight: '500',
},
priceText:{
color:'#400D33',
fontSize:10,
fontWeight:'300',
textAlign:'center',
paddingTop:5
},
addBtn:{
backgroundColor:'white',
position:'absolute',
left:'23%',
width:'10%',
height:'15%',
justifyContent:'center',
alignItems:'center',
borderRadius: 5,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
zIndex:1
}
});
export default ProductCard;
And This is the output:
I have been trying to solve it by changing things couldn't figure out the main problem. If somebody know the solution, please help me out. I'll be vary grateful to you.
Thank In Advance
CodePudding user response:
I believe your problem is that you are positioning the button absolutely so they are stacking on top of each other in each row column. A quick fix would be to nest the button within the TouchableOpacity below it. I assume that you would like the button to be at the right edge of the screen and so instead of using left I align it to the flex-end:
import React from 'react';
import {
TouchableOpacity,
Image,
View,
Text,
StyleSheet,
Dimensions
} from 'react-native';
const screenDimensions = Dimensions.get('screen');
const {width, height} = screenDimensions
const ProductCard = ({ image, title, price, onPress }) => {
return (
<>
<TouchableOpacity style={styles.container} onPress={onPress}>
<TouchableOpacity
style={styles.addBtn}
onPress={() => {
alert('Item Added');
}}>
<Image
source={require('../Assets/PNGs/Products/add.png')}
resizeMode={'contain'}
style={{ width: 15, height: 15 }}
/>
</TouchableOpacity>
<View style={styles.card}>
<Image
source={{ uri: `${image}` }}
resizeMode="stretch"
style={{ width: '80%', height: '80%' }}
/>
</View>
<View style={styles.titleView}>
<Text numberOfLines={2} style={styles.titleStyle}>
{title}
</Text>
<Text style={styles.priceText}>${price}</Text>
</View>
</TouchableOpacity>
</>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'space-between',
width: width * (25 / 100),
height: height * (22 / 100),
marginHorizontal: '3.5%',
marginBottom: '2%',
},
card: {
height: '60%',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 5,
borderRadius: 5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
backgroundColor: 'white',
},
titleView: {
flex: 0.9,
alignItems: 'center',
},
titleStyle: {
width: '100%',
fontSize: 12,
textAlign: 'center',
color: '#6E1033',
fontWeight: '500',
},
priceText: {
color: '#400D33',
fontSize: 10,
fontWeight: '300',
textAlign: 'center',
paddingTop: 5,
},
addBtn: {
backgroundColor: 'white',
position: 'absolute',
// left: '23%',
alignSelf:'flex-end',
width: '10%',
height: '15%',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
zIndex: 1,
},
});
export default ProductCard;
Here's an expo snack where you can see it in action