Home > Net >  button above the view is only displayed on the first column of flatList of react Native
button above the view is only displayed on the first column of flatList of react Native

Time:07-17

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:

enter image description here

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 how it look Here's an expo snack where you can see it in action

  • Related