androidlayoutreact-native

React Native image takes up all vertical space available


I am new to react-native (started 2 days ago) but I picked it up quickly because I already knew regular react. I'm trying to write a real world app and I can't figure out how to place an image correctly, I want my Image tag to take up all horizontal space on the screen, but I also want it to stay at the very top of the screen and keep its aspect ratio (which I can't hardcode because I will also display other pictures of licence plates, including european ones that are not 2/1 like in north america), all while not having the actual image take up all available vertical space.

Here is a GIMP edit of what my code renders and what I actually want: https://ibb.co/XJgrhkC

Here is my render function:

export default class App extends Component {
  ...

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'flex-start', alignItems: 'center' }}>
        <Image
          source={require(`./resources/images/north_america/original/alaska.jpg`)}
          style={{ flex: 1, width: screenWidth }}
          resizeMode="contain" />
        <Button title="Random state" onPress={this.getRandomState} />
      </View>
    );
  }
}

I am familiar with css's layout options but react-native seems to be different and I can't wrap my head around all the combinations of widths, flex and resizeModes.


Solution

  • When you use flex, you can see the image automatically occupying a lot of space when you add {borderWidth: 2, borderColor: 'red'}. Instead, you have to specify the height manually. If you want it to be scaled properly, you can try this:

    import React from "react";
    import { View, Image, Button, Dimensions } from "react-native";
    
    class App extends React.Component {
      state = {
        imgWidth: 0,
        imgHeight: 0
      };
    
      componentDidMount() {
        Image.getSize("https://i.ibb.co/HgsfWpH/sc128.jpg", (width, height) => {
          // Calculate image width and height
          const screenWidth = Dimensions.get("window").width;
          const scaleFactor = width / screenWidth;
          const imageHeight = height / scaleFactor;
          this.setState({ imgWidth: screenWidth, imgHeight: imageHeight });
        });
      }
      render() {
        return (
          <View
            style={{ flex: 1, justifyContent: "flex-start", alignItems: "center" }}
          >
            <Image
              style={{
                flex: 1,
                width: Dimensions.get("window").width,
                borderColor: "red",
                borderWidth: 2
              }}
              source={{
                uri: "https://i.ibb.co/HgsfWpH/sc128.jpg"
              }}
              resizeMode="contain"
            />
            <Button title="Random state" onPress={this.getRandomState} />
          </View>
        );
      }
    }
    
    export default App;