Closed joshbedo closed 9 years ago
canvas: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
<Image
resizeMode="contain"
source={{uri: 'http://imgs.steps.dragoart.com/how-to-draw-a-pony-step-7_1_000000053055_5.jpg'}}
style={styles.canvas} />
Try out stretch
and cover
for alternative resizeMode
s too
Here's a full example that integrates it using position: relative
in the parent to constrain it:
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
Image,
} = React;
var SampleApp = React.createClass({
render: function() {
return (
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.container}>
<Image
resizeMode="contain"
source={{uri: 'http://imgs.steps.dragoart.com/how-to-draw-a-pony-step-7_1_000000053055_5.jpg'}}
style={styles.canvas} />
</View>
<View style={styles.container}>
<Text>Hello!</Text>
</View>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
position: 'relative'
},
canvas: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
If this doesn't resolve your problem feel free to re-open.
@brentvatne awesome, i actually solved it by changing the container styles around. alignItems:'center'
was causing the child image element to not show for some reason.
I can confirm the alignItems
fix as well. In general, I find it very fiddly to figure out how combination of properties works, and the results are different depending on whether the source is local or not.
I believe that https://github.com/facebook/react-native/issues/2804#issuecomment-148723052 might be related to this also.
Seems like you guys were struggeling with the same thing as me. I have an image not showing up though my code pretty much seems to be equal to @joshbedo's first post (see code below). As soon as I add a fixed height like for instance 300
to my imageWrapper
style the image shows up. Does anybody have an idea?
import React, { Component, Image, PropTypes, View } from 'react-native'
import Dimensions from 'Dimensions'
let window = Dimensions.get('window')
const prefix = 'http://my-image-server.com/images/'
class MyImage extends Component {
render() {
let imageUrl = prefix + this.props.type + '/' + (this.props.size || 1080) + '/' + this.props.filename + '.jpg'
return (
<View style={styles.imageWrapper}>
<Image style={styles.image} source={{uri: imageUrl}}/>
</View>
)
}
}
MyImage.propTypes = {
type: PropTypes.string.isRequired,
filename: PropTypes.string.isRequired,
size: PropTypes.string
}
let styles = {
imageWrapper: {
flex: 1,
alignItems: 'stretch'
},
image: {
flex: 1
}
}
export default MyImage
I have done according to this, Hope this code snippet might help you.
<Image style={styles.bgContainer} resizeMode='cover' source={require('./img/bg.png')} />
const styles = StyleSheet.create({ bgContainer: { flex:1, width: null, height: null } });
Above @yashvekaria solution worked for me
I have done without flex.
local image
<View>
<Image
style={{height: 100, width: null}}
source={require('./ad.png')}
/>
</View>
network image
<View>
<Image
style={{height: 100}}
source={{uri: 'http://xxx.com/ad.png'}}
/>
</View>
@yashvekaria's and @clinyong's solution (adding a width: null
) worked for me, and I am very curious as to why. Why is setting it to null
different from not setting it at all?
@clinyong How would you do width: 100%, height: auto
in react-native?
@vini175pa you can use react-native-extended-stylesheet for that, but the problem is that when the devices rotates the values are not updated...
@vinpac try this:
Get image width and height with:
Image.getSize(path, ({ width, height }) => {
this.setState({ width, height });
});
Then do this:
<Image
source={{...}}
style={{
width: Dimensions.get('window').width,
height: Dimensions.get('window').width * this.state.height / this.state.width
}}
resizeMode={'cover'}
/>
Not a pretty way, but it works.
Hi,
I ran into the same issue as well. Some of the solutions didn't quite work for me. For instance the previous solution by @superandrew213 would have the image filling the width of the window but often you want the image to fill/respect the width of its parent container. Here's what I tried that works:
<View style={{flexDirection:'row'}}>
<Image
source={...}
resizeMode="contain"
style={{flexShrink:1}}
/>
</View>
The key point is to get the image to be in a row layout using flexDirection:'row'
in its container then the image has resizeMode='contain'
in order for it to maintain its aspect ratio and style with flexShrink:1
to make sure it doesn't horizontally overflow its container.
Hmm, I noticed that these examples only worked when a flex has been specified for all parent views/components. The image itself needs flex: 1, width: null, height: null at a minimum. Anyways this worked for me to display the image on the top half of the screen:
<View style={{flex: 1}}>
<View style={{flexDirection: "row", flex: 1}}>
<Image source={{uri: "https://vestigo.co/images/yoga-outside.jpg"}} style={{flex: 1, resizeMode: "stretch", width: null, height: null}} />
</View>
<View style={{flex: 2}}>
</View>
</View>
@joshbedo the parent alignItems sets to center , cause the Image not show , does any one knows why? change the parent alignItems and flex:1 for the Image fix the problem for me .
@danywheeler If you set alignItems
to "center" on the parent then it changes it from the default "stretch". This causes the image then to not have any space if you don't specify a width and height
@clinyong your method works great in my iOS simulator.
When I view it via Expo on my Android phone I get
Error while updating property 'width' in shadow node of type: RCTTextInlineImage
Looks like we can't use null. Stackoverflow answer here.
Your solution was so slick.. I'd like to keep using it. Ideas? Is this an Android thing?
I tried wiping out as many style options as possible and finding the minimal set of styles required to reach the goal. You don't need containers or anything, just an Image. Apparently the "width:null" bit is important:
<Image
style={{ width: null }}
resizeMode="contain"
source={require('./img/catfish.jpg')}
/>
If you need it to fit with other elements:
<Image
style={{ flex:1, width: null }}
resizeMode="contain"
source={require('./img/catfish.jpg')}
/>
Following on from @maludwig 's solution, to get a 100% width image that has a specific height, this works:
<Image
source={require('../images/space.jpeg')}
style={{ height: 290, width: null }}
resizeMode="cover"
/>
Posting this here in case anyone gets in the same trouble as i have. I wanted to be able to put an image in a container and have it fill to that container. The following seems to work so far in any situation. The view wrapping the image with flexDirection of row is what it all hinges on which may be me just being bad still getting used to flex positioning.
<View
style={{flex:1,flexDirection: 'row'}}>
<Image
resizeMode='contain'
style={{
flex:1,
width:null,
height:null}}
source={Images[status]}
/>
</View>
@jwtea Thank you! Your variant works for me, but I changed resize mode to 'cover' and now it works perfect!
Getting <Image>
width:100% and height auto is so finicky. Trying on Android right now. Always such a battle.
What I do now is have an image component that based on the width/height of the image it sets the flex properties and such so that I can achieve width 100% without changing the aspect ratio and without the image overflowing its container. The source for my images are set with require('...')
so Image.getSize()
doesn't work on them but the following does and works synchronously:
const resolveAssetSource = require('resolveAssetSource')
let { width, height } = resolveAssetSource(imageSource)
@jwtea solution is working with me like a charm 🎉 known that I am using flex containers
I gave up and had to create an Image component with onLoad
to get the source image/width and then setState to set the image dimensions. I will revisit later, this is too much overhead for something so simple.
@Noitidart Totally agreed. The team made the decision to not mimic the concept of automatically sizing images and maintaining their aspect ratio as it is on the web. I can see the pros for that but boy it sure is a pain to get an image to be width 100% (yet not wider than it's container) while having the height automatically adjust. It's such a common use-case that it would be nice to have something for this out of the box someday
For me nothing worked except this approach: https://stackoverflow.com/a/42556256 Other solutions depend top container configurations / styling
I agree with @Noitidart. We've been dealing with image tags since the birth of WWW. Why is it still so difficult and wonky requiring dozens of kludgy workarounds? I've tried nearly every suggestion here. So far, none of them have worked. I'm just venting. So feel free to ignore.
How should I proceed, If I have to show full width and auto height of images inside a list (flatlist/sectionlist/listview) like the Instagram app?
The current Examples work well as in Individual Component only, When I put the component inside renderItem of flatlist the images don't show.
<FlatList data={['a', 'b', 'c']}
renderItem={({ item }) => (
<View>
<Text>{item}</Text>
<Image
style={{ flex:1, width: null, height: null } }
resizeMode="contain"
source={{ uri: 'http://www.transphone.net/images/android-transfer/android-screenshot2.jpg'}} />
</View> )}
/>
Any Help is much Appreciated.
Here's a module I made that does exactly this https://www.npmjs.com/package/react-native-fullwidth-image
I found that @jwtea 's solution almost worked for me (thanks Jack!), but although the image was scaled horizontally, there was excessive automatic padding (whitespace) inserted above and below the image. Adding an aspectRatio
with correct values for my image solved this:
<View
style={{flex: 1, flexDirection: 'row'}}>
<Image
resizeMode='contain'
style={{
flex: 1,
width: null,
height: null,
aspectRatio: 926/606}}
source={Images[status]}
/>
</View>
In my case my image was 926 wide and 606 high, so I just used those values directly. A more sensible developer might have simplified the aspect ratio of their source image first to e.g. 16/9!
For me, this works across both Android and iOS, tested on a few device sizes.
Here is my solution;
const img = (source) => {
const { width, height } = Image.resolveAssetSource(source)
return <Image source={source} style={{ width: null, height: null, resizeMode: 'cover', aspectRatio: width / height }} />
}
<View style={{ flexDirection: 'row' }}>
<View style={{ flex:2 }}>
{img(require('./assets/images/1.png'))}
</View>
<View style={{ flex:1 }}>
{img(require('./assets/images/2.png'))}
</View>
</View>
I'm attempting to make an image full-width and came across a few stackoverflow questions related where the top upvoted answer was to use flexbox similarly to how i'm using it below. Although it doesn't seem to display the image unless i set static widths on my
styles
property. Any ideas?