I have a query regarding tag. I want an image to take entire width of parent which I do using alignSelf:stretch, but I also want the height to be according to the aspect ra
You may use something like this:
<View style={{height:200}} >
<Image source={require('image!MyImage') style={{ resizeMode:Image.resizeMode.ratio, flex:1 }}} />
</View>
Please not that you still have to set the height on the view container.
I like bdv's approach and I use this kind of images almost everywhere in my app. That's why I created an own component which is using onLayout
to also support device rotation.
import resolveAssetSource from 'resolveAssetSource';
import React, {Component} from 'react';
import {Image, View} from 'react-native';
export default class FullWidthImage extends Component {
constructor() {
super();
this.state = {
width: 0,
height: 0
};
}
_onLayout(event) {
const containerWidth = event.nativeEvent.layout.width;
if (this.props.ratio) {
this.setState({
width: containerWidth,
height: containerWidth * this.props.ratio
});
} else if (typeof this.props.source === 'number') {
const source = resolveAssetSource(this.props.source);
this.setState({
width: containerWidth,
height: containerWidth * source.height / source.width
});
} else if (typeof this.props.source === 'object') {
Image.getSize(this.props.source.uri, (width, height) => {
this.setState({
width: containerWidth,
height: containerWidth * height / width
});
});
}
}
render() {
return (
<View onLayout={this._onLayout.bind(this)}>
<Image
source={this.props.source}
style={{
width: this.state.width,
height: this.state.height
}} />
</View>
);
}
}
You can use it like this:
<FullWidthImage source={{uri: 'http://example.com/image.jpg'}} />
<FullWidthImage source={require('./images/image.jpg')} />
Or if you know the ratio like this:
<FullWidthImage source={{uri: 'http://example.com/image.jpg'}} ratio={0.5} />
<FullWidthImage source={require('./images/image.jpg')} ratio={0.5} />
I tried the Image.getSize approach, but had problems, since we gather all the image links in a config file and then pass the ImageURISource into the source prop of the Image.
My solution for that was to wait for the Image onLayout callback to get it's layout properties and use that to update the dimensions. I created a component for that:
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);
};
}
This will update the dimensions of the image to match the width of the screen.
You can use react-native-scalable-image. The following example will do the job:
import React from 'react';
import { Dimensions } from 'react-native';
import Image from 'react-native-scalable-image';
const image = <Image width={Dimensions.get('window').width} source={{uri: '<image uri>'}} />;
Use style={{ aspectRatio: 3/2 }}
for a horizontal image with width to height ratio of 3:2.
Docs: https://facebook.github.io/react-native/docs/layout-props.html#aspectratio
(Available in RN 0.40+)
Typically, doing the following would give us an image rendered to max width/height depending on orientation while maintaining the aspect ratio of the image itself:
render(){
return(<Image style={{'width': Dimensions.get('window').width,
'height': Dimensions.get('window').height}}
resizeMode='contain'
source='[URL here]'
</Image>);
}
Using 'contain' with resizeMode: Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding).
Update: * Unfortunately, it seems that there is a common bug with resizeMode's 'contain' specifically when using react native for Android: https://github.com/facebook/react-native/pull/5738*