asus
asus

Reputation: 1759

React Native - Image bigger than parent

Like in tinder, i have a screen with 3 Image Pickers. When I pick an image from the gallery, I want it to persist inside the TouchableOpacity container. However, the image overlaps the container.

I have been been trying various things mentioned here but the image still overlaps like in the image below:

overlapped image

What is the problem?

/* eslint-disable react-native/no-inline-styles */
import React, { useState } from 'react'
import {
  Text,
  View,
  Image,
  Button,
  TouchableOpacity,
  StyleSheet,
  Dimensions,
} from 'react-native'
import ImagePicker from 'react-native-image-crop-picker'
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'
import { faPlusCircle } from '@fortawesome/free-solid-svg-icons'
import Colors from '../../../constants/Colors'
const { width: WIDTH } = Dimensions.get('window')

const ProfileEdit = () => {
  const [photo, setPhoto] = useState(null)

  const handleChoosePhoto = () => {
    ImagePicker.openPicker({
      width: 300,
      height: 400,
      cropping: true,
    }).then((image) => {
      setPhoto({
        uri: image.path,
        width: image.width,
        height: image.height,
        mime: image.mime,
      })
      console.log(image)
    })
  }

  return (
    <View style={styles.main}>
      <View style={styles.button_row}>
        <View style={styles.buttonWrapper}>
          <TouchableOpacity
            onPress={() => handleChoosePhoto()}
            style={styles.button}>
            {photo ? (
              <Image source={photo} style={styles.photo} />
            ) : (
              <FontAwesomeIcon
                icon={faPlusCircle}
                color={Colors.defaultColor}
                size={22}
                style={styles.icon}
              />
            )}
          </TouchableOpacity>
        </View>
        <View style={styles.buttonWrapper}>
          <TouchableOpacity
            onPress={() => handleChoosePhoto()}
            style={styles.button}>
            <FontAwesomeIcon
              icon={faPlusCircle}
              color={Colors.defaultColor}
              size={22}
              style={styles.icon}
            />
          </TouchableOpacity>
        </View>
        <View style={styles.buttonWrapper}>
          <TouchableOpacity
            onPress={() => handleChoosePhoto()}
            style={styles.button}>
            <FontAwesomeIcon
              icon={faPlusCircle}
              color={Colors.defaultColor}
              size={22}
              style={styles.icon}
            />
          </TouchableOpacity>
        </View>
      </View>
    </View>
  )
}

const styles = StyleSheet.create({
  main: {
    flex: 1,
  },
  icon: {},
  button: {
    height: `${100}%`,
    backgroundColor: Colors.defaultWhite,
    padding: 2,
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 3,
  },
  buttonWrapper: {
    width: WIDTH / 3,
    padding: 10,
  },
  button_row: {
    flex: 0.3,
    flexWrap: 'wrap',
    flexDirection: 'row',
  },
  photo: {
    width: WIDTH / 2,
    height: WIDTH / 2,
    // borderRadius: 3,
    resizeMode: 'contain',
  },
})

export default ProfileEdit

Upvotes: 1

Views: 1630

Answers (3)

Anurag Shrivastava
Anurag Shrivastava

Reputation: 692

I prefer ImageBackground instead. Below is the code to achieve you the desired View:

 <ImageBackground
     imageStyle={styles.image}
     style={styles.imageContainer}
     source={{uri: this.state.imageUri}}>
         <TouchableOpacity onPress={this._pickImage} style={{
                           height: WIDTH/2,
                           width: WIDTH/2,
                           justifyContent: "center",
                           alignItems: "center"}}>
                                
                <Entypo name="camera" color={Colors.GREY} size={35}/>
                               
          </TouchableOpacity>
  </ImageBackground>

Upvotes: 0

asus
asus

Reputation: 1759

correct answer as described here

"However because images will try to set the width and height based on the actual size of the image, you need to override these style properties"

<Image
  style={{
    flex: 1,
    alignSelf: 'stretch',
    width: undefined,
    height: undefined
  }}
  source={require('../../assets/images/onboarding-how-it-works.png')}
/>

Upvotes: 2

glinda93
glinda93

Reputation: 8459

Instead of calculating image width try this:

<TouchableOpacity
  onPress={() => handleChoosePhoto()}
  style={styles.button}>
  {photo ? (
    <View style={styles.photoContainer}>
        <Image source={photo} style={styles.photo} />
    </View>
  ) : (
    <FontAwesomeIcon
      icon={faPlusCircle}
      color={Colors.defaultColor}
      size={22}
      style={styles.icon}
    />
  )}
</TouchableOpacity>

const styles = StyleSheet.create({
    photoContainer: {
        // flex: 1 
    },
    photo: {
        height: WIDTH / 2,
        width: '100%',
        resizeMode: 'contain'
    }
});

Upvotes: 0

Related Questions