React Native - 如何使图像宽度为 100% 且顶部垂直?
React Native - How to make image width 100 percent and vertical top?
我是 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/
谢谢。
图片垂直居中,因为您在 属性 样式中添加了 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}}
/>
也试一试
您还可以等待 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);
};
}
这将更新图像的尺寸以匹配屏幕的宽度。
您可以将此样式应用于图像:
如果将 imageStyle
应用于 Image
标签,则图片宽度将为 100%,图片高度将为 300。
imageStyle:{
height:300,
flex:1,
width:null
}
假设你的图片代码是:
<Image style={imageStyle} source={{uri:'uri of the Image'}} />
右键单击您的图像以获得分辨率。在我的例子中 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" />
那都
我有一个组件可以获取图像道具并进行适当的调整(并在 ScrollView
和 require
d 资产中工作。在滚动视图中,它使用图像的高度作为高度,无论它是否缩放都会导致一些多余的填充。此组件执行大小计算并重新调整图像样式以使用 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 一起使用,您需要添加一个填充视图作为第一个 child
<View
style={{
height: safeAreaInsets.top + (Platform.OS === "ios" ? 96 : 44),
}}
/>
我是 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/
谢谢。
图片垂直居中,因为您在 属性 样式中添加了 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}}
/>
也试一试
您还可以等待 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);
};
}
这将更新图像的尺寸以匹配屏幕的宽度。
您可以将此样式应用于图像:
如果将 imageStyle
应用于 Image
标签,则图片宽度将为 100%,图片高度将为 300。
imageStyle:{
height:300,
flex:1,
width:null
}
假设你的图片代码是:
<Image style={imageStyle} source={{uri:'uri of the Image'}} />
右键单击您的图像以获得分辨率。在我的例子中 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" />
那都
我有一个组件可以获取图像道具并进行适当的调整(并在 ScrollView
和 require
d 资产中工作。在滚动视图中,它使用图像的高度作为高度,无论它是否缩放都会导致一些多余的填充。此组件执行大小计算并重新调整图像样式以使用 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 一起使用,您需要添加一个填充视图作为第一个 child
<View
style={{
height: safeAreaInsets.top + (Platform.OS === "ios" ? 96 : 44),
}}
/>