React Native Images for Multiple Screens - image

I have an image which I want to display in top half of my screen. I'm using flux like this.
<View style={{flex:0.5}}>
<Image
style={{width:null, height:null, flex:1, resizeMode:'stretch'}}
source={require('../../../Images/salad-congo.png')}>
</Image>
</View>
<View style={{flex:0.5, backgroundColor:'yellow'}}>
<Text>Hello</Text>
</View>
Problem:
The problem is my image does not fit for all screen sizes. If I'm opening my app in landscape mode the image is centered instead of covering whole width and height of upper half. In case I use 'resizeMode='stretch'' my whole image is destroyed in pixels, and becomes un viewable. How can I make my image appear big for large screens, and small for small screens obviously covering the whole screen. Is there something I need to do with my image's resolutions? Or provide multiple images? If yes then how to handle them for both android and IOS

Import Dimensions From react native and then use it to set the size of your image
import {Dimensions} from 'react-native'
const SCREEN_WIDTH = Dimensions.get("window").width;
const logo = require("logo.png");
in the return of render:
<Image source={logo} style={styles.logo} />
const styles = StyleSheet.create({
logo: {
height: SCREEN_WIDTH * 0.65,
width: SCREEN_WIDTH * 0.65,
marginLeft: SCREEN_WIDTH * 0.2
}})

So I solved the issue by creating a single large image of 2056x2056, and then by using Flex properly to obtain the desired result. Tested the result on a couple of phones and tablets. Working Fine.
<View style={{flex:1}}>
<View style={{flex:0.6, alignItems:'stretch'}}>
<Image style={{flex:1, width: null, height: null }}
source={require('../../../Images/salad-congo2056x2056.png')}/>
</View>
<View style={{flex:0.1, backgroundColor:'#ffffff'}}>
// Intentional gap
</View>
<View style={{flex:0.3, backgroundColor:'red'}}>
// Anything here
</View>
</View>

Related

Elevation of An TouchableOpacity Not Working on Carousel Image, React Native

<View style={{alignItems:'center',marginTop: 15, height:320,backgroundColor:'#fff',paddingTop:10}}>
<TouchableOpacity style={{position:'absolute',right:15,top:25,elevation:2}}>
<Icon name="share-social-outline" size={30} color="#0057ff"/>
</TouchableOpacity>
<Carousel
autoplay
autoplayTimeout={5000}
loop
index={0}
pageSize={BannerWidth}
>
{images.map((image, index) => renderPage(image, index, navigation))}
</Carousel>
</View>
</View>
I used TouchableOpacity on icon and Gave Elevation to Touchable Opacity which is on image carousel, Its Not working. Please Help
I got the answer by experimenting myself; In Order To get Touchableopacity on icon over Image Carousel, we just need to use 'zIndex=3' Not 'elevation'.

React Native: Image with 100% height

I have an image that should always take 100% of the parent size. The width should adjust accordingly to maintain the aspect ratio of the image. The width can be smaller or larger than the parent. The height must be equal to the parent size.
<View style={{height: 220}}>
<Image source={{uri: 'myuri.jpg'}} style={{height: '100%, ...?}} />
</View>
I only find solutions where the width is fixed and the height adjusts dynamically. I want it the other way round.
import { Dimensions } from 'react-native';
You can get the application window's width and height using the following code:
<View style={{height: Dimensions.get("window").height}}>
<Image source={{uri: 'myuri.jpg'}}
style={{
height: Dimensions.get("window").height*0.5,
width: Dimensions.get("window").width
}}
/>
</View>
Using this way you can proportion the size you want.
You can also review the document here.
Dimensions
Try this
<View style={{height: 220}}>
<Image source={{uri: 'myuri.jpg'}} style={{height: '100%, width: 'auto'}} />
</View>
Also resizeMode: 'contain' can helps you a lot.
Reference that might helps you: https://reactnative.dev/docs/image#resizemode

Preload, cache gif Images to avoid flickering in React Native

I am trying to create an animation in react native where a character do some push ups.
Going up and down is done at the moment I want.
So I separated a gif animation in 2 gifs, without repetition. One to make him going up and the other one to make him going down..
These images are locally stored
The problem is that there is a flickering when the gif change.
I tried react-fast-image, but the gif animation is too slow and the gif is looped automatically.
I tried to put a transition image in the meatime images are switching but still a flicker behaviour.
The image onLoadEnd callback seems to be called too early, before the image actually ends up to load.
here how I switch the images
if (up.includes(this.props.timer))
this.setState({ currentGif: upGif, cacheImage: downPng })
if (down.includes(this.props.timer))
this.setState({ currentGif: downGif, cacheImage: upPng })
Here is the render:
render() {
return (
<View
style={{ position: 'absolute', bottom: 70 }}
>
<Image
source={this.state.cacheImage}
style={{ width: 400, height: 330, position: 'relative', bottom: 70 }}
fadeDuration={0}
/>
<Image
source={this.state.currentGif}
style={{ width: 400, height: 330, position: 'absolute', bottom: 70 }}
fadeDuration={0}
onLoadEnd={() => {this.setState({cacheImage: null})}} // the Image should be loaded so I can hide the cache Image, but it desapear before the gif is loaded
/>
</View>
)
}
You can use the Image.getSize API.
To get the size, RN downloads and caches the image. It's stated in the docs that this method can be used for preloading images. They also mention that a more explicit API will be provided in the future, so you can use this for now and switch to a better API when it's available.

How to resize image from URL and display fixed width on React Native?

Somehow I could not figure this out. I have tried several solutions available online, but none of them worked.
Here is the issue. I have some wide images that I wanted to stack on top of each other. The height does not matter, but I want it to have a fixed width. For some reason, the images are being cropped.
I want it to look like this. For example, if you change .meat's height to 10px, it will resize but will maintain its ratio.
http://jsfiddle.net/iggyfiddle/mtL7e2jz/
This is the image code:
{items.map((item, index) =>
<View key={index}>
<View style={styles.imageWrapper}>
{ item.image_url_large && <Image style={styles.image} resizeMode='cover' source={{ uri: item.image_url_large }} /> }
</View>
</View>
)}
It is mapping over an array of several images.
I have tried:
a simple
const styles = {
image: {
height: 100
},
};
I tried following the same pattern on the fiddle, by giving it fixed height and width according to this SO post
const styles = {
imageWrapper: {
height: 50,
width: 400
},
image: {
height: '100%'
},
};
But it still crops the top bun and tomato
I have tried some solutions described on this GH discussion but they don't seem to work.
How can I automatically resize the image from web to fixed width without it being cropped?
use resizeMode='contain' instead of cover and specify the width and height.
<Image
style={{width:300,height:300}}
source={{ uri: display_image_small }}
resizeMode='contain'>
</Image>

How to dynamically scale an image in react-native?

I want an image to appear across the width of the screen, and be scaled so it retains its proportions.
I currently have this
<ScrollView style={styles.background}>
<Text>Some Header Text</Text>
<Image
style={{width: null}}
resizeMode="contain"
source={require("./assets/images/map.png")}
/>
</ScrollView>
which half works. The image is scaled correctly in width. but it is retaining its height, so there is a large border above and below the image.(ie the layout is still using the images height unscaled)
If I add a height: null or replace the width with a height then no image is displayed.
How do I do this (I expect) trivial thing?
(same behavior on ios and android.)
So I have had to calculate things myself.
This scales the image as I want, and the image is re-scaled when the phone is rotated.
I am not sure if componentWillMount is the right event to choose to calculate the width/height ratio. I would be happy for any other code review comments!
import React, {Component} from "react";
import {
StyleSheet,
Text,
View,
ScrollView,
Image,
Button,
Dimensions
} from "react-native";
import resolveAssetSource from "resolveAssetSource";
import {Actions} from "react-native-router-flux";
export default class Main extends Component {
measureView(event) {
this.setState({
width: event.nativeEvent.layout.width,
height: event.nativeEvent.layout.width
});
}
componentWillMount() {
let source = resolveAssetSource(require("./assets/images/map.png"));
this.setState({ratio: source.height / source.width});
}
render() {
return (
<ScrollView
onLayout={event => this.measureView(event)}
>
<Text style={styles.header}>
Some Header Text
</Text>
<Image
style={{
width: this.state.width,
height: this.state.width * this.state.ratio
}}
resizeMode="contain"
source={require("./assets/images/map.png")}
/>
</ScrollView>
);
}
}

Resources