React Native - How to make image width 100 percent and vertical top?

Viewed 83640

I am newbie at react-native. What I want to do is that fit an image in device and keep the ratio of image. Simply I want to make width : 100%

I searched how to make it and seems resizeMode = 'contain' is good for that.

However, since I used resizeMode = 'contain', the image keeps the position vertically centered which I don't want. I want it to be vertically top.

I tried to use a plug-in such as react-native-fit-image but no luck.

And I found the reason why the image is not sizing automatically. But still I have no idea how to make it.

So, my question is what is the best way to deal with this situation?

Do I have to manually put width, height size each images?

I want :

  • Keep image's ratio.
  • Vertically top positioned.

React native test code :

https://snack.expo.io/ry3_W53rW

Eventually what I want to make :

https://jsfiddle.net/hadeath03/mb43awLr/

Thanks.

6 Answers

You can Apply this style to image: If you apply imageStyle to the Image tag then the Image width will be 100% and Image height will be 300.

imageStyle:{
height:300,
flex:1,
width:null
}

Suppose you Image Code is:

<Image style={imageStyle} source={{uri:'uri of the Image'}} />

Right click on you image to get resolution. In my case 1233 x 882

const { width } = Dimensions.get('window');

const ratio = 882 / 1233;

    const style = {
      width,
      height: width * ratio
    }

<Image source={image} style={style} resizeMode="contain" />

That all

I have a component that takes image props and does the proper adjustments (and works within a ScrollView and with required assets. Inside a scroll view it uses the height of the image as the height regardless if it is scaled that causes some excess padding. This component performs size computations and readjusts the image style to work with a 100% width preserving the aspect ratio of the file that was loaded.

import React, { useState } from "react";
import { Image, ImageProps } from "react-native";

export function FullWidthImage(props: ImageProps) {
  // Initially set the width to 100%
  const [viewDimensions, setViewDimensions] = useState<{
    width?: number | string;
    height?: number | string;
  }>({
    width: "100%",
    height: undefined,
  });

  const [imageDimensions, setImageDimensions] = useState<{
    width?: number;
    height?: number;
  }>(() => {
    if (typeof props.source === "number") {
      // handle case where the source is an asset in which case onLoad won't get triggered
      const { width, height } = Image.resolveAssetSource(props.source);
      return { width, height };
    } else {
      return {
        width: undefined,
        height: undefined,
      };
    }
  });
  return (
    <Image
      onLayout={(e) => {
        // this is triggered when the "view" layout is provided
        if (imageDimensions.width && imageDimensions.height) {
          setViewDimensions({
            width: e.nativeEvent.layout.width,
            height:
              (e.nativeEvent.layout.width * imageDimensions.height) /
              imageDimensions.width,
          });
        }
      }}
      onLoad={(e) => {
        // this is triggered when the image is loaded and we have actual dimensions.
        // But only if loading via URI
        setImageDimensions({
          width: e.nativeEvent.source.width,
          height: e.nativeEvent.source.height,
        });
      }}
      {...props}
      style={[
        props.style,
        {
          width: viewDimensions.width,
          height: viewDimensions.height,
        },
      ]}
    />
  );
}

This is to compensate for contain which adds extra padding around the image (which is basically making the image view height full) even if the image width is 100%.

Note chances are you are trying to put it in as a background, in which case ImageBackground does not renders correctly on Android. Using the above code a few tweaks I created the following that renders things correctly with long and short text.

import React, { PropsWithChildren } from "react";
import { ImageProps, View } from "react-native";
import { FullWidthImage } from "./FullWidthImage";

export function FullWidthImageBackground(props: PropsWithChildren<ImageProps>) {
  const imageProps = { ...props };
  delete imageProps.children;
  return (
    <View>
      <FullWidthImage
        {...imageProps}
        style={{
          position: "absolute",
        }}
      />
      {props.children}
    </View>
  );
}

Note if you are using it with a header, you need to add a padding view as the first child

<View
  style={{
    height: safeAreaInsets.top + (Platform.OS === "ios" ? 96 : 44),
  }}
/>

You can Apply this style to image: If you apply Image to the Image tag then the Image width full image.

const win = Dimensions.get('window');
export default function App() {
  
  return (
    <View style={styles.container}>

       <Image
       style={{
        width: win.width/1,
        height: win.width/5,
        resizeMode: "contain",
        alignSelf: "center",
        borderRadius: 20,
      }}
        source={require('./assets/logo.png')}
      />


    </View>
  );
}
Related