有一种方法可以使用远程图像,而不依赖于全屏宽度测量。首先,您需要确定调整大小的图像不应跨越的图像组件的边界。它本质上是定义
width
和
height
其中将包含图像。我把这些当作
宽度
和
高度
道具
ImageWithBorders
(屏幕截图上的绿色边框)
之后,您可以通过以下方式获取远程图像尺寸
Image.getSize
,计算比率并进行一些数学运算,以确定视图的适当视图尺寸
class ImageWithBorders extends React.Component {
constructor(props) {
super(props)
this.state = {
// image wrapper dimensions
iWidth: null,
iHeight: null,
// image dimensions
iiWidth: null,
iiHeight: null,
// outer wrapper dimensions
vWidth: null,
vHeight: null
}
}
componentDidMount() {
Image.getSize(this.props.source,
(iWidth, iHeight) => {
this.setState({ iWidth, iHeight })
}
)
}
// using onLayout in case non-numeric dimensions were passed
_onLayout = ({ nativeEvent: { layout: { height, width } } }) => {
this.setState({ vWidth: width, vHeight: height })
};
componentDidUpdate(prevProps, prevState) {
const {
iWidth: oldiWidth,
iHeight: oldiHeight,
vWidth: oldvWidth,
vHeight: oldvHeight
} = prevState
const {
iWidth,
iHeight,
vWidth,
vHeight
} = this.state
if (oldiWidth === null || oldiHeight === null || oldvWidth === null || oldvHeight === null) {
if (iWidth && iHeight && vWidth && vHeight) {
// at this moment both view and remote image were measured
// now use some math to calculate proper sizes for all views
const { borderWidth } = this.props
const border2 = borderWidth * 2
if (vWidth - border2 < vHeight - border2) {
const newImageWidth = vWidth - border2
const imageRatio = iHeight / iWidth
const newImageHeight = newImageWidth * imageRatio
this.setState({
iHeight: newImageHeight + border2,
iWidth: vWidth,
iiHeight: newImageHeight,
iiWidth: newImageWidth,
measured: true
})
} else {
const newImageHeight = vHeight - border2
const imageRatio = iHeight / iWidth
const newImageWidth = newImageHeight / imageRatio
this.setState({
iHeight: vHeight,
iWidth: newImageWidth + border2,
iiHeight: newImageHeight,
iiWidth: newImageWidth,
measured: true
})
}
}
}
}
render() {
const { source, height = 0, width = 0, resizeContainer = false } = this.props
const outerWidth = resizeContainer ? this.state.measured ? this.state.iWidth : width : width
const outerHeight = resizeContainer ? this.state.measured ? this.state.iHeight : height : height
return (
<View
style={{
width: outerWidth,
height: outerHeight,
borderWidth: 1,
borderColor: 'green',
alignItems: 'center',
justifyContent: 'center'
}}
onLayout={this._onLayout}
>
<View
style={{
width: this.state.iWidth || 0,
height: this.state.iHeight || 0,
backgroundColor: 'red',
alignItems: 'center',
justifyContent: 'center'
}}
>
<Image
source={source}
style={{
width: this.state.iiWidth,
height: this.state.iiHeight,
}}
resizeMode={'contain'}
/>
</View>
</View>
)
}
}
这样使用它
const App = () => {
return (
<View
style={{
alignItems: 'center',
justifyContent: 'center',
...StyleSheet.absoluteFillObject
}}
>
<ImageWithBorders
source={{ uri: 'https://i.imgur.com/BWrNPE4.png' }}
borderWidth={13}
height={400}
width={260}
resizeContainer={false} // or true
/>
<ImageWithBorders
source={{ uri: 'https://i.imgur.com/BWrNPE4.png' }}
borderWidth={5}
height={100}
width={260}
resizeContainer={false} // or true
/>
</View>
)
}
resizeContainer
道具会将图像调整到最终的宽度和高度,而不是在关闭时保持原始的宽度和高
树脂容器
设置为false:
树脂容器
设置为true:
当然,这只是一个最小的工作示例。您可能希望添加其他功能,例如在样式中传递宽度和高度、更改边框颜色,以及在道具动态更改时重新运行计算(现在它只会调整一次大小,如果您在运行时更改borderWidth等,它将不会再次调整大小)