react-nativestylesheetcamera-roll

React Native - Adding margin: 1 in Camera Roll


How to add margin: 1 perfectly in my Camera Roll? Because when I add margin: 1 in my <Image .../> the order will not be in correct order.

The result I want is like in the Instagram. There's no margin in the Left and Right Side, right?

Just like this Image:

enter image description here

Here are my Codes:

render() {
return(
  <View style={styles.container}>
    {/* <SelectedImage source={{uri: this.state.pickedImage}}/> */}
    <Image source={{uri: this.state.pickedImage}} style={styles.image}/>
    <ScrollView contentContainerStyle={styles.scrollView} showsVerticalScrollIndicator={false}>
      {this.state.photos.map((photos, index) => {
        return(
          <TouchableHighlight 
            style={{opacity: index === this.state.index ? .5 : 1}}
            onPress={() => this.setState({pickedImage: photos.node.image.uri})}
            key={index}
            underlayColor='transparent'
          >
            <Image
              style={{width: width / 3, height: width /3}}
              source={{uri: photos.node.image.uri}}
              resizeMode='cover'
            />
          </TouchableHighlight>
        );
      })}
    </ScrollView>
  </View>
); 
}
}

const styles = StyleSheet.create({
container: {
 height: '100%',
 width: '100%',
 justifyContent: 'center',
 alignItems: 'center',
 backgroundColor: 'white'
},
scrollView: {
 flexWrap: 'wrap',
 flexDirection: 'row'
},
scrollViewContainer: {
 flex: 1,
 flexDirection: 'row',
},
 image: {
 width: '100%',
 height: 300,
 backgroundColor: 'black'
}
});

This is the Result on my own: (Dont't bother of the Black Border I just didn't crop perfectly and I have just 6 Photos in my Android Emulator).

enter image description here

Answer Suggested:

componentDidMount() {
this.getPhotos();
this.rightButtonIcon();
requestExternalStoragePermission();

photoFilter = () => {
  var arr = this.state.photos;
  var number = 0;
  arr.forEach((item) => {
    switch(number) {
      case 0: 
        number = 1;
        item.position="left"
      break;
      case 1:
        number = 2;
        item.position="center"
      break;
      case 2: 
        number = 0;
        item.position="right"
      break;
      default:
        return null;
    }
  })
  this.setState({photos: arr})
}
};

 imageStylePositionCalc = (pos) =>{
  if(pos==="left") return {marginRight:1,marginBottom:1}
  if(pos==="center") return {marginRight:1,marginBottom:1}
  if(pos==="right") return {marginBottom:1}
 }

  render() {
return(
  <View style={styles.container}>
    {/* <SelectedImage source={{uri: this.state.pickedImage}}/> */}
    <Image source={{uri: this.state.pickedImage}} style={styles.image}/>
    <ScrollView contentContainerStyle={styles.scrollView} showsVerticalScrollIndicator={false}>
      {this.state.photos.map((photos, index) => {
        return(
          <TouchableHighlight 
            style={{opacity: index === this.state.index ? .5 : 1}}
            onPress={() => this.setState({pickedImage: photos.node.image.uri})}
            key={index}
            underlayColor='transparent'
          >
            <Image
              style={[{width: width / 3, height: width /3}, this.imageStylePositionCalc(photos.position)]}
              source={{uri: photos.node.image.uri}}
              resizeMode='cover'
            />
          </TouchableHighlight>
        );
      })}
    </ScrollView>
  </View>
); 
}
}

This is the another Problem, the margin: 1 taking over the full width of the screen and there is no margin in the 2nd row:

enter image description here


Solution

  • Before doing the map, I would suggest to go trough every part of the array and add a value that says if it will be placed into the right, left or center. Something like:

    photoFilter=()=>{
       var arr=this.state.photos;
       var number=0;
       arr.forEach((item)=>{
          switch (number){
             case 0: 
                number=1;
                item.position="left"
                break;  
             case 1: 
                number=2;
                item.position="center"
                break;  
             case 2: 
                number=0;
                item.position="right"
                break; 
             default:
                return null 
          }
      })
    this.setState({photos:arr})
    }
    

    then, when rendering the image:

    <Image
    style={[{width: width / 3, height: width /3},this.imageStylePositionCalc(item.position)]}
    source={{ uri: photos.node.image.uri }}
    resizeMode="cover"
    />
    

    then add a function:

    imageStylePositionCalc=(pos)=>{
      if(pos==="left") return {marginRight:1,marginBottom:1}
      if(pos==="center") return {marginRight:1,marginBottom:1}
      if(pos==="right") return {marginBottom:1}
    }
    

    This may not be the best answer but should work

    UPDATE: The problem is that you are defining the photoFilter function inside the didMount.

    What i meant when i said to call it inside componentDidMount was:

    componentDidMount() {
    this.getPhotos();
    this.rightButtonIcon();
    requestExternalStoragePermission();
    this.photoFilter
    }
    
    photoFilter = () => {
          var arr = this.state.photos;
          var number = 0;
          arr.forEach((item) => {
            switch(number) {
              case 0: 
                number = 1;
                item.position="left"
              break;
              case 1:
                number = 2;
                item.position="center"
              break;
              case 2: 
                number = 0;
                item.position="right"
              break;
              default:
                return null;
            }
          })
          this.setState({photos: arr})
        }