如何在本机反应中将图像宽度设置为 100% 并将高度设置为自动?
Posted
技术标签:
【中文标题】如何在本机反应中将图像宽度设置为 100% 并将高度设置为自动?【英文标题】:How to set image width to be 100% and height to be auto in react native? 【发布时间】:2017-01-30 14:37:52 【问题描述】:我正在尝试在滚动视图中显示图像列表。宽度应该是 100%,而高度应该是自动的,保持纵横比。
我所做的搜索指向了提供全屏背景样式的各种解决方案。
const styles = StyleSheet.create(
image:
width: null,
height: 300,
resizeMode: 'cover'
);
<ScrollView style=flex: 1>
<Image style=styles.image source=require('../../../images/collection-imag1.png')/>
<Image style=styles.image source=require('../../../images/collection-imag2.png')/>
</ScrollView>
我尝试了各种宽度组合:null,高度:null,flex:1,alignSelf 等。上述解决方案几乎可以工作,除了高度不是动态的。部分图像不可见。
【问题讨论】:
看看react-native-scalable-image 【参考方案1】:所以经过一段时间的思考,我能够达到 height: auto in react-native image。 您需要知道图像的尺寸才能使此 hack 起作用。只需在任何图像查看器中打开您的图像,您就会在文件信息中获得图像的尺寸。 作为参考,我使用的图像尺寸为 541 x 362
首先从 react-native 导入维度
import Dimensions from 'react-native';
那么你必须得到窗口的尺寸
const win = Dimensions.get('window');
现在计算比率为
const ratio = win.width/541; //541 is actual image width
现在为您的图像添加样式
imageStyle:
width: win.width,
height: 362 * ratio, //362 is actual height of image
【讨论】:
你是天才。我仍然无法弄清楚这一点。但它有效:) 这么聪明的解决方案 截至 2020 年 3 月,这仍然是最佳解决方案吗? 是的!这是唯一一个在所有情况下都有效的。唯一要考虑的是,如果这些是静态资产,您可以很容易地解析图像尺寸。只需:import myImage from '../../assets/myimage.png'; const width, height = Image.resolveAssetSource(myImage)
非常感谢。它也适用于 2021 年。为什么 React 团队从来没有构建一些功能来让开发人员更容易做到这一点?【参考方案2】:
"resizeMode"
不是样式属性。应该移动到 Image 组件的Props
,如下面的代码。
const win = Dimensions.get('window');
const styles = StyleSheet.create(
image:
flex: 1,
alignSelf: 'stretch',
width: win.width,
height: win.height,
);
...
<Image
style=styles.image
resizeMode='contain' /* <= changed */
source=require('../../../images/collection-imag2.png') />
...
图像的高度不会自动生成,因为在style props
中,图像 组件的宽度和高度都需要。所以你可以使用getSize()方法来计算像this answer这样的远程图像,你也可以计算像this answer这样的静态图像的图像比例。
有很多有用的开源库 -
react-native-auto-height-image react-native-fullwidth-image react-native-fit-image【讨论】:
它是图像的样式属性,根据facebook.github.io/react-native/docs/image.html。将其更改为属性也不起作用。 这不能回答自动计算高度的给定问题 这行得通,但你应该说你需要“从'react-native'导入Dimensions;” 这并不能从很多角度回答这个问题。除了上述 cmets 中所说的之外,the doc 明确表示 getSize() “不适用于静态图像资源”。 @Betty 我认为 getSize() 确实适用于静态图像。【参考方案3】:如果您知道图像的 aspectRatio (width / height),我已经找到了 width: "100%", height: "auto" 的解决方案。
代码如下:
import Image, StyleSheet, View from 'react-native';
const image = () => (
<View style=styles.imgContainer>
<Image style=styles.image source=require('assets/images/image.png') />
</View>
);
const style = StyleSheet.create(
imgContainer:
flexDirection: 'row'
,
image:
resizeMode: 'contain',
flex: 1,
aspectRatio: 1 // Your aspect ratio
);
这是不使用onLayout
或Dimension
计算的最简单方法。如果需要,您甚至可以将其包装在一个简单的可重用组件中。如果有人正在寻找简单的实现,请试一试。
【讨论】:
【参考方案4】:我对上述所有解决方案都有疑问。最后我使用 aspectRatio 来解决这个问题。当您知道图像的宽度和高度并且它们很大时,只需计算 aspectRatio 并将其添加到图像中,如下所示:
<PhotoImage
source=uri: `data:image/jpeg;base64,$image.base64`
style= aspectRatio: image.width / image.height
/>
AspectRatio 是 React Native 的一个布局属性,用于保持图像的纵横比并适合父容器:https://facebook.github.io/react-native/docs/layout-props#aspectratio
【讨论】:
这是唯一真正的答案。对此进行扩展。如果您从网络请求图像。您可以使用来自react-native
的Image.getSize
静态方法获取大小【参考方案5】:
在样式中使用 aspectRatio 属性
纵横比控制节点未定义维度的大小。纵横比是一个非标准属性,仅在 react native 中可用,在 CSS 中不可用。
在具有设置宽度/高度纵横比的节点上控制 未设置的维度 在具有设置弹性基准纵横比的节点上控制 如果未设置,则在交叉轴上的节点 在具有测量函数纵横比的节点上,就像 measure 函数测量弹性基础 在具有 flex 增长/收缩纵横比的节点上控制 如果未设置,则在交叉轴上的节点 纵横比考虑了最小/最大尺寸文档:https://reactnative.dev/docs/layout-props#aspectratio
试试这样:
import Image, Dimensions from 'react-native';
var width = Dimensions.get('window').width;
<Image
source=
uri: '<IMAGE_URI>'
style=
width: width * .2, //its same to '20%' of device width
aspectRatio: 1, // <-- this
resizeMode: 'contain', //optional
/>
【讨论】:
【参考方案6】:您始终必须设置Image
的宽度和高度。它不会自动为您调整大小。 React Native 文档says so。
您应该使用onLayout
测量ScrollView
的总高度,并根据它设置Image
s 的高度。如果您使用resizeMode
或cover
,它将保持Image
s 的纵横比,但如果它比容器大,它显然会裁剪它们。
【讨论】:
仅自动调整大小不适用于远程图像。 OP 正在引用一个本地的静态图像文件,用 React Native 的话 “可以自动调整大小,因为它们的尺寸在安装时立即可用。”【参考方案7】:2020 年 4 月解决方案:
所以上面的答案很可爱,但他们都有一个很大的缺陷(imo):他们正在计算图像的高度,基于用户设备的宽度。
要拥有一个真正响应式(即width: 100%, height: auto
)实现,您真正想要做的是计算图像的高度,基于在父容器的宽度上。
幸运的是,React Native 为我们提供了一种获取父容器宽度的方法,这要感谢onLayout View method。
所以我们需要做的就是用width: "100%"
创建一个View,然后用onLayout
得到那个view的宽度(即容器宽度),然后用那个容器宽度来适当地计算我们图像的高度.
给我看代码...
可以通过使用RN's Image.getSize 进一步改进以下解决方案,以在 ResponsiveImage 组件本身中获取图像尺寸。
JavaScript:
// ResponsiveImage.ts
import React, useMemo, useState from "react";
import Image, StyleSheet, View from "react-native";
const ResponsiveImage = props =>
const [containerWidth, setContainerWidth] = useState(0);
const _onViewLayoutChange = event =>
const width = event.nativeEvent.layout;
setContainerWidth(width);
const imageStyles = useMemo(() =>
const ratio = containerWidth / props.srcWidth;
return
width: containerWidth,
height: props.srcHeight * ratio
;
, [containerWidth]);
return (
<View style=styles.container onLayout=_onViewLayoutChange>
<Image source=props.src style=imageStyles />
</View>
);
;
const styles = StyleSheet.create(
container: width: "100%"
);
export default ResponsiveImage;
// Example usage...
import ResponsiveImage from "../components/ResponsiveImage";
...
<ResponsiveImage
src=require("./images/your-image.jpg")
srcWidth=910 // replace with your image width
srcHeight=628 // replace with your image height
/>
TypeScript:
// ResponsiveImage.ts
import React, useMemo, useState from "react";
import
Image,
ImageSourcePropType,
LayoutChangeEvent,
StyleSheet,
View
from "react-native";
interface ResponsiveImageProps
src: ImageSourcePropType;
srcWidth: number;
srcHeight: number;
const ResponsiveImage: React.FC<ResponsiveImageProps> = props =>
const [containerWidth, setContainerWidth] = useState<number>(0);
const _onViewLayoutChange = (event: LayoutChangeEvent) =>
const width = event.nativeEvent.layout;
setContainerWidth(width);
const imageStyles = useMemo(() =>
const ratio = containerWidth / props.srcWidth;
return
width: containerWidth,
height: props.srcHeight * ratio
;
, [containerWidth]);
return (
<View style=styles.container onLayout=_onViewLayoutChange>
<Image source=props.src style=imageStyles />
</View>
);
;
const styles = StyleSheet.create(
container: width: "100%"
);
export default ResponsiveImage;
// Example usage...
import ResponsiveImage from "../components/ResponsiveImage";
...
<ResponsiveImage
src=require("./images/your-image.jpg")
srcWidth=910 // replace with your image width
srcHeight=628 // replace with your image height
/>
【讨论】:
正如您所建议的那样,github.com/vivaxy/react-native-auto-height-image 解决了这个问题。谢谢【参考方案8】:右键单击您的图像以获得分辨率。在我的情况下 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" />
全部
【讨论】:
【参考方案9】:对于图像标签,您可以使用这种样式,它对我有用:
imageStyle:
width: Dimensions.get('window').width - 23,
resizeMode: "contain",
height: 211,
,
【讨论】:
resizeMode 不能是样式 @KaushilRuparelia 绝对可以【参考方案10】:让我分享一下我最终得到的结果,它允许通过获取图像尺寸来正确设置宽度或高度。此外,该代码允许在传输我们需要的大图像数据时获取加载图像:
使用静态方法 Image.prefetch 下载图像并用于缓存。
使用静态方法Image.getSize收集高度和宽度,并用它来计算纵横比,然后计算最终高度(或宽度)
以您喜欢的宽度显示具有默认样式的图像(高度将在保持纵横比的情况下计算)
function ImageX(props: source: string, id: string)
const [imageHeight, setImageHeight] = React.useState(1);
Image.prefetch(props.source)
.then(() =>
Image.getSize(props.source, (width, height) =>
let aspectRatio = height/width;
setImageHeight(aspectRatio*Dimensions.get('window').width);
);
)
.catch(error => console.log(error))
if (imageHeight <=1) //Image not in cache (disk) yet
return (
<Image key=props.id style=styleimg.image source=uri: 'http://www.dsdsd/loaderpreview.gif'/>
);
else
return (
<Image key=props.id style=styleimg.image height=imageHeight source=uri: props.source/>
);
const styleimg = StyleSheet.create( 图片: 宽度:Dimensions.get('window').width, 调整大小模式:'包含' //... // 您可以设置高度默认值 );
【讨论】:
【参考方案11】:这可能有助于自动调整具有 100% 宽度的图像高度
图片: 宽度:“100%”, resizeMode:“中心”“包含”, 高度:未定义, 纵横比:1,
【讨论】:
【参考方案12】:function ImageX( props)
const [state, setState] = React.useState(v:height:1);
useEffect(() =>
if(!props.source || !props.source.uri) return;
Image.prefetch(props.source.uri)
.then(() =>
Image.getSize(props.source.uri, (width, height) =>
let aspectRatio = height/width;
state.v.width=Dimensions.get('window').width;
state.v.height=aspectRatio*state.v.width;
setState(...state);
);
)
.catch(error => console.log(error))
,[props.source && props.source.uri]);
if (state.v.height <=1) //Image not in cache (disk) yet
return (
<Image ...props/>
);
else
let neededst=v:width:state.v.width, height:state.v.height
let st=v:props.style;
assignObject(neededst, st);
return (
<Image ...props style=neededst.v/>
);
function assignObject(target, source)
if (!source) return;
for (let k in target)
let v = target[k];
if (Object(v) === Object) assignObject(v, source[k]);
else
if (source[k])
try
Object.assign(v, source[k]);
catch (e)
alert(e);
for (let k in source)
if (!target[k])
target[k] = source[k];
使用来自https://reactnativeelements.com/docs/image的图片组件
【讨论】:
以上是关于如何在本机反应中将图像宽度设置为 100% 并将高度设置为自动?的主要内容,如果未能解决你的问题,请参考以下文章