【问题标题】:React Native - How to make image width 100 percent and vertical top?React Native - 如何使图像宽度 100% 和垂直顶部?
【发布时间】:2017-12-24 13:28:31
【问题描述】:

我是 react-native 的新手。 我想要做的是将图像适合设备并保持图像的比例。只是我想做width : 100%

我搜索了如何制作它,似乎resizeMode = 'contain' 很适合。

但是,由于我使用了resizeMode = 'contain',因此图像保持垂直居中的位置,这是我不想要的。 我希望它是垂直顶部。

我尝试使用react-native-fit-image 之类的插件,但没有成功。

我找到了the reason why the image is not sizing automatically。 但我仍然不知道如何制作。

那么,我的问题是处理这种情况的最佳方法是什么?

我必须手动将width, height 设置为每个图像的大小吗?

我想要:

  • 保持图片的比例。
  • 垂直顶部定位。

React 原生测试代码:

https://snack.expo.io/ry3_W53rW

最终我想做什么:

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

谢谢。

【问题讨论】:

标签: react-native image-resizing


【解决方案1】:

我有一个组件,它采用图像道具并进行适当的调整(并在 ScrollViewrequired 资产中工作。在滚动视图中,它使用图像的高度作为高度,无论它是否缩放会导致一些多余的填充。此组件执行大小计算并重新调整图像样式以使用 100% 宽度保持加载文件的纵横比。

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,
        },
      ]}
    />
  );
}

这是为了补偿contain,即使图像宽度为100%,它也会在图像周围添加额外的填充(这基本上是使图像视图高度变满)。

请注意,您可能正试图将其作为背景放入,在这种情况下,ImageBackground 无法在 Android 上正确呈现。使用上面的代码进行了一些调整,我创建了以下内容,可以正确呈现长文本和短文本。

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>
  );
}

注意如果你使用的是header,你需要添加一个padding view作为第一个child

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

【讨论】:

    【解决方案2】:

    右键单击您的图像以获得分辨率。在我的情况下 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" />
    

    全部

    【讨论】:

      【解决方案3】:

      您可以将此样式应用于图像: 如果将imageStyle 应用于Image 标签,则图像宽度将为100%,图像高度为300。

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

      假设你的图像代码是:

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

      【讨论】:

      • 当我添加 null 时,图像消失了。
      【解决方案4】:

      图像垂直居中,因为您将flex: 1 添加到样式属性中。不要添加 flex: 1,因为这会将图像填充到其父级,这在这种情况下是不需要的。

      您应该始终在 React Native 中为图像添加高度和宽度。如果图像始终相同,您可以使用Dimensions.get('window').width 来计算图像的大小。例如,如果比例始终为 16x9,则高度为图像宽度的 9/16。宽度等于设备宽度,所以:

      const dimensions = Dimensions.get('window');
      const imageHeight = Math.round(dimensions.width * 9 / 16);
      const imageWidth = dimensions.width;
      
      return (
         <Image
           style={{ height: imageHeight, width: imageWidth }}
         />
      );
      

      注意:使用这样的实现时,您的图像在旋转设备、使用分屏等时不会自动调整大小。如果您支持多个方向,您也必须注意这些操作。 .

      如果比例不同,请根据每个不同图像的比例动态更改 9 / 16。如果你不介意图像被裁剪了一点,你也可以使用固定高度的封面模式:(https://snack.expo.io/rk_NRnhHb)

      <Image
        resizeMode={'cover'}
        style={{ width: '100%', height: 200 }}
        source={{uri: temp}}
      />
      

      【讨论】:

      • 感谢您的回答。所以我必须知道图像大小并使用尺寸来控制图像大小。
      • 在您的博览会示例中,为什么要放置 width: '100%' ?我认为它不起作用。
      • 100% 仅适用于较新版本的 React Native(如果我没记错的话,从 0.43 开始)
      • 未来的访问者,使用Dimensions 将在设备旋转时惨遭失败。您需要绑定方向更改和反向宽度/高度。这不是一个优雅的解决方案。 RN 应该更好地处理这个问题。
      【解决方案5】:

      只是为了试一试

      您也可以等待 Image onLayout 回调来获取它的布局属性并使用它来更新尺寸。我为此创建了一个组件:

      import * as React from 'react';
      import { Dimensions, Image, ImageProperties, LayoutChangeEvent, StyleSheet, ViewStyle } from 'react-native';
      
      export interface FullWidthImageState {
        width: number;
        height: number;
        stretched: boolean;
      }
      
      export default class FullWidthImage extends React.Component<ImageProperties, FullWidthImageState> {
        constructor(props: ImageProperties) {
          super(props);
      
          this.state = { width: 100, height: 100, stretched: false };
        }
      
        render() {
          return <Image {...this.props} style={this.getStyle()} onLayout={this.resizeImage} />;
        }
      
        private resizeImage = (event: LayoutChangeEvent) => {
          if (!this.state.stretched) {
            const width = Dimensions.get('window').width;
            const height = width * event.nativeEvent.layout.height / event.nativeEvent.layout.width;
            this.setState({ width, height, stretched: true });
          }
        };
      
        private getStyle = (): ViewStyle => {
          const style = [StyleSheet.flatten(this.props.style)];
          style.push({ width: this.state.width, height: this.state.height });
          return StyleSheet.flatten(style);
        };
      }
      

      这将更新图像的尺寸以匹配屏幕的宽度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        • 2016-01-22
        相关资源
        最近更新 更多