react native absolute positioning makes image crop - react-native

I have a problem with positioning my image inside a container and that is when I give image position: absolute and top property image got cropped from the top here's the issue:
here's my code:
<View style={styles.OurTherapistsContainer}>
<View style={styles.therapistCard}>
<View style={styles.imageContainer}>
<Image style={styles.image} source={require('../assets/img/leong.png')} />
</View>
</View>
</View>
...
therapistCard: {
width: 150,
height: 150,
borderRadius: 25,
borderWidth: 1,
borderColor: '#DFEEFF',
overflow: 'hidden',
},
imageContainer: {
width: 150,
height: 150,
backgroundColor: 'red',
},
image: {
width: '100%',
height: '100%',
position: "absolute",
top: 30
}
how can I fix this?

Try using resizeMode in image style like
resizeMode:'contain'

set resizeMode to cover
<Image style={styles.image} resizeMode="cover" source {require('../assets/img/leong.png')} />

Related

set borderRadius with resizeMode contain in react-native without knowing dimensions of image

Any ideas how to add borderRadius to the image that has resizeMode set to contain, and no knowledge of height and width?
The code currently looks like this, but this doesn't work.
<View
style={[
styles.imageContainerWrapper,
{ width: width },
]}
key={i}
>
<Image
source={{ uri: url }}
borderRadius={normalize(20)}
resizeMode="contain"
style={{
height: '100%',
maxWidth: '100%',
maxHeight: '100%',
overflow: 'hidden',
backgroundColor: 'blue',
}}
/>
Add borderRadius to the style property of the Image like this:
<View
style={[
styles.imageContainerWrapper,
{ width: width },
]}
key={i}
>
<Image
source={{ uri: url }}
resizeMode="contain"
style={{
height: '100%',
maxWidth: '100%',
maxHeight: '100%',
overflow: 'hidden',
backgroundColor: 'blue',
borderRadius: 20,
}}
/>

Vertically center image that's not affected by KeyboardAwareScrollView in React Native

Alright, so this has got me busy for quite a few hours already. I am trying to create a login screen where the main components are rendered on the bottom, with the logo in the remaining space. This is kind of what I would like to achieve:
To support my textinputs, I use KeyboardAwareScrollView, as it works better for me as opposed to KeyboardAvoidingView. My code currently looks like this (I plan on using a background image with a 50% color overlay rather than the red background, so the ImageBackground has to stay in place too):
<ImageBackground
source={require('./assets/img/background-clouds.png')}
resizeMode="cover"
style={styles.backgroundImage}>
<View style={styles.backgroundOverlay} />
<View style={styles.dummyView}>
<Text>elloha</Text>
</View>
<Image
source={require('./assets/img/logo.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
keyboardOpeningTime={0}
alwaysBounceHorizontal={false}
alwaysBounceVertical={false}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
automaticallyAdjustContentInsets={false}
extraScrollHeight={30}
enableOnAndroid>
<StatusBar
backgroundColor="transparent"
barStyle="light-content"
hidden={false}
translucent
/>
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
accessible={false}>
<View style={styles.content}>
<View style={styles.backgroundContainer}>
<SafeAreaView style={{ flex: 0 }} />
<View style={styles.loginContainer}>
<View style={styles.loginScreen}>
// textinputs and buttons go here
</View>
<SafeAreaView style={{ backgroundColor: 'white' }} />
</View>
<View
style={{
backgroundColor: 'white',
height: Dimensions.get('window').height,
position: 'absolute',
width: Dimensions.get('window').width,
top: Dimensions.get('window').height,
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAwareScrollView>
</ImageBackground>
Relevant styles:
const styles = StyleSheet.create({
container: {
backgroundColor: "white",
},
content: {
flex: 1,
},
backgroundImage: {
flex: 1,
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
backgroundContainer: {
justifyContent: "flex-end",
flex: 1,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
},
backgroundOverlay: {
backgroundColor: "red",
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
},
logoContainer: {
top: "10%",
width: "100%",
},
backgroundLogo: {
alignSelf: "center",
position: "absolute",
width: 126,
height: 96,
},
dummyView: {
backgroundColor: "red",
flex: 1,
},
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: "100%",
backgroundColor: "white",
height: 500,
alignItems: "center",
paddingTop: Dimensions.get("window").width * 0.1,
},
loginScreen: {
width: "80%",
backgroundColor: "white",
},
});
This yields the following result:
I can get it done by adding top: 160 to the backgroundLogo style, but that's a fixed value. I want it to be always in the center of the available space, but I'm unable to add a view between the background and the loginContainer, as all the logic for the keyboard and such is handled in between.
Is there a way to achieve what I want? Ideally, I should also be able to check the available height, and only show the logo if there is enough space (e.g. available height > 100, otherwise don't show logo).
Important:
I want the logo to stay fixed, so if the keyboard is shown, the logo should not move up. The loginContainer should go "over" the logo
EDIT:
Wrap Image inside a View with this style and give the loginContainer style height: '70%' :
...
<View style={styles.dummyView}>
<Text>elloha</Text>
</View>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
height: '30%',
position: 'absolute',
width: '100%',
}}>
<Image
source={require('./assets/img/logo.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
</View>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
...
...
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: '100%',
backgroundColor: 'orange',
height: '70%',
alignItems: 'center',
paddingTop: Dimensions.get('window').width * 0.1,
},
...
hie! I think using Dimension to get a specific screen's height and deciding it has 70% of the screen covered via form sheet and rest is free for a logo to be in and we can ask it to be down a little using rest of height's 50% as margin-top ( the image will be in the center of that image )
here is a SNACK LINK to see your example working with my suggested solution.
here is the draft code:
import * as React from 'react';
import { Text, View, StyleSheet, Dimensions, ImageBackground,TextInput,
Image, TouchableWithoutFeedback, Keyboard, SafeAreaView, StatusBar} from 'react-native';
import Constants from 'expo-constants';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
export default function App() {
return (
<ImageBackground
source={{
uri: 'https://cdn.pixabay.com/photo/2021/08/23/18/37/tea-6568547_960_720.jpg',
}}
resizeMode="cover"
style={styles.backgroundImage}>
<View style={styles.backgroundOverlay} />
<Image
source={require('./assets/snack-icon.png')}
style={styles.backgroundLogo}
resizeMode="contain"
/>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="always"
keyboardOpeningTime={0}
alwaysBounceHorizontal={false}
alwaysBounceVertical={false}
contentInsetAdjustmentBehavior="automatic"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
automaticallyAdjustContentInsets={false}
extraScrollHeight={30}
enableOnAndroid>
<StatusBar
backgroundColor="transparent"
barStyle="light-content"
hidden={false}
translucent
/>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={styles.content}>
<View style={styles.backgroundContainer}>
<SafeAreaView style={{flex: 0}} />
<View style={styles.loginContainer}>
<View style={styles.loginScreen}>
<TextInput value={'email'} style={{borderBottomWidth:1, padding:10}}/>
<TextInput value={'password'} style={{borderBottomWidth:1, padding:10}}/>
</View>
<SafeAreaView style={{backgroundColor: 'white'}} />
</View>
<View
style={{
backgroundColor: 'white',
height: Dimensions.get('window').height,
position: 'absolute',
width: Dimensions.get('window').width,
top: Dimensions.get('window').height,
}}
/>
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAwareScrollView>
</ImageBackground>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
},
content: {
flex: 1,
},
backgroundImage: {
flex: 1,
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
backgroundContainer: {
justifyContent: 'flex-end',
flex: 1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
backgroundOverlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
},
logoContainer: {
top: '10%',
width: '100%',
},
backgroundLogo: {
alignSelf: 'center',
position: 'absolute',
marginTop: Dimensions.get('window').height/7, // top for rest of the screen to push logo down
width: 126,
height: 96,
},
dummyView: {
backgroundColor: 'red',
flex: 1,
},
loginContainer: {
borderTopEndRadius: 30,
borderTopStartRadius: 30,
width: '100%',
backgroundColor: 'white',
height: Dimensions.get('window').height/1.5, //container of form height
alignItems: 'center',
paddingTop: Dimensions.get('window').width * 0.1,
},
loginScreen: {
width: '80%',
backgroundColor: 'white',
},
});
Here is the output of code on android/ios:

Image borderRadius is not working in react native

I have used borderRadius in Image and loop it. It works in some images however others are rectangular. If I touch it then it shows the radius and disappears as soon as it is untouched. Using overflow hidden doesn't do the trick as well.
I'm confused I used the same style but the result is different. I've tested it on Android devices only.
https://snack.expo.io/#codebyte99/multiplearrays
code:
<TouchableOpacity activeOpacity={0.8}>
<ImageBackground
source={{
uri: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREX0q18KDbtN-obe1EFxAwNg27xgR_KItZ7U8MkXnH7zBCEr_ASQ",
}}
style={[
{
width: 200,
height: 80,
resizeMode: "center",
justifyContent: "flex-end",
alignItems: "center",
margin: 5,
marginRight: 0,
marginTop: 0,
marginBottom: 5,
borderRadius: 6,
overflow: "hidden",
},
]}
>
<Text>{childItem.title}</Text>
</ImageBackground>
</TouchableOpacity>;
You have to set the borderRadius to Image, not in style:
<Image source={{...}} borderRadius={6} .../>
And you don't set overflow: 'hidden' in image style, but in the View:
<View style={{ ..., overflow: 'hidden' }}>
<Image ..../>
</View>
Wrap the Image in a View with overflow: "hidden" and apply borderRadius to that, e.g.
<View
style={{
width: 30,
height: 30,
borderRadius: 15,
overflow: "hidden",
}}
>
<Image
style={{ width: 30, height: 30}}
source={{ uri }}
></Image>
</View>
(I could not find a way to get borderRadius to work on the image directly on Android.)
Applying the same fixed height and width to the image and borderRadius as half of the (height/width) will solve the border issue for android in react-native. Note: Make sure you have resizeMode as 'cover'
<Image key={index} source={{ 'uri' }} resizeMode='cover' style={{ height: 40, width: 40, borderRadius: 20 }} />

React-Native: image resizeMode not working properly

I'm having issues trying to set resizeMode: 'cover' in Image component
This image summarizes my issue :
I'm testing it on Android, RN 0.55.3 and this my sample code
<View style={{ width: 200, height: 200, backgroundColor: '#555' }}>
<Image
source={require('./bird.jpg')}
style={{ alignSelf: 'stretch', flex: 1, resizeMode: 'cover' }}
/>
</View>
Also tried :
<View style={{ width: 200, height: 200, backgroundColor: '#555' }}>
<Image
source={require('./bird.jpg')}
style={{ alignSelf: 'stretch', flex: 1 }}
resizeMode='cover'
/>
</View>
But neither is working, so is there any way to get it work properly ?
I found that resizeMode doesn't work properly unless I set the width of the Image
I used width: 'auto' and everything worked well
the final code :
<View style={{ width: 200, height: 200, backgroundColor: '#555' }}>
<Image
source={require('./bird.jpg')}
style={{ alignSelf: 'stretch', flex: 1, resizeMode: 'cover', width: 'auto' }}
/>
</View>
I define Image tag as below. resizeMode outside the style.
<View style={{ width: 200, height: 200, backgroundColor: '#555' }}>
<Image
source={require('./bird.jpg')}
style={{ alignSelf: 'stretch', flex: 1,width : 'auto'}}
resizeMode={'cover'}
/>
</View>
this works for me.

React native position absolute

I want to fix my Image. I use position: 'absolute', in iOS it works fine, but in android the image disappear. This is my code:
<Image style={{width: width, zIndex: 0, position: 'absolute', top: 0}}
source={require('../assets/2piano.png')}
resizeMode="contain"
/>
Please HELP!!!
This will work on both Android and iOS. Since your image is from the local resources you should give it a width:null and height:null in order to apply your own dimensions on it.
<View style={{width: 500, height:500}}>
<Image style={{width: null, height:null, zIndex: 0, position: 'absolute', top: 0, bottom:0, left:0, right:0}}
source={require('../assets/2piano.png')}
resizeMode="contain"
/>
</View>
For style:
twoPianoStyle: {
position: 'absolute',
height: '100%',
width: '100%'
}