I am adding image background to my app, but the horizontal part of the image went past the screen (the right and left part got cut). I tried to use resizeMode cover and contain but both of it didn't do anything. Is there any other way to make the image stay within the screen? (I use resizeMode on Image and it contain the image normally {same picture}).
import React from 'react';
import {
Image,
ImageBackground,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {DCTBACKGROUND} from '../../../assets/images';
export default function GetStarted({navigation}) {
return (
<ImageBackground source={DCTBACKGROUND} style={styles.page}>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={() => {
navigation.navigate('Register');
}}>
<Text style={styles.buttonText}>Registrasi</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => {
navigation.navigate('Login');
}}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
</View>
</ImageBackground>
);
}
const styles = StyleSheet.create({
page: {
backgroundColor: '#90CC8B',
flex: 1,
paddingHorizontal: 15,
paddingVertical: 25,
// resizeMode: 'contain',
},
button: {
backgroundColor: 'yellow',
width: 100,
height: 40,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
},
buttonText: {
color: 'black',
},
buttonContainer: {
justifyContent: 'space-between',
flexDirection: 'row',
},
logo: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
},
});
The image horizontal part got cut a bit and I need to make it all show without being cut.
Add the resizeMode as a direct prop to the ImageBackground and not as part of the StyleSheet.
<ImageBackground resizeMode="contain" source={DCTBACKGROUND} style={styles.page}>
Related
I have tried so many combinations of using containers that I don't know what else to do. Also, all the buttons must have equal dimensions, and the section of buttons must stretch to the end of the screen.
Start with a parentContainer with a row flexDirection so that items are laid left to right instead of up and down.
Add two views to parentContainer: imageContainer and buttonContainer. Divvy width among the two according to your layout desires (image from question suggest 50%/50%)
add centering styles to imageContainer and use onLayout to determine width and height of image.
add row flexDirection and flexWrap to buttonContainer.
Create a buttonStyle make sure it has width of 50%
Here's a snack that brings it all together:
import * as React from 'react';
import { Image, Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
const Button = ({ title, titleStyle, ...touchableProps }) => {
return (
<TouchableOpacity
{...touchableProps}
style={[styles.button, touchableProps.style]}>
<Text style={[{ textAlign: 'center' }, titleStyle]}>{title}</Text>
</TouchableOpacity>
);
};
export default function App() {
// used to set image size
const [{ width, height }, setViewDimensions] = React.useState({});
// update image size on imageview layout chagnes
const onLayout = ({ nativeEvent: { layout } }) => setViewDimensions(layout);
return (
<View style={styles.container}>
<View style={styles.parentContainer}>
<View style={styles.imageContainer} onLayout={onLayout}>
<Image
source={require('./assets/snack-icon.png')}
style={{ width, height: width }}
resizeMode="contain"
/>
</View>
<View style={styles.buttonContainer}>
<Button title="1" />
<Button title="2" />
<Button title="3" />
<Button title="4" />
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
parentContainer: {
flex: 1,
flexDirection: 'row',
},
imageContainer: {
width: '50%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'lightblue',
},
buttonContainer: {
width: '50%',
backgroundColor: 'lightgreen',
flexDirection: 'row',
flexWrap: 'wrap',
},
button: {
width: '50%',
alignItems: 'center',
justifyContent: 'center',
borderColor: 'white',
borderBottomWidth: 1,
borderRightWidth: 1,
},
});
One of my React Native screens needs to have a TouchableOpacity at the bottom of the screen. I've tried setting position: "absolute" and bottom: 0, however, this just causes the element to be a few hundred pixels below the screen. How can I make my TouchableOpacity be at the bottom of the screen all the time?
<View style={styles.mainView}>
<View style={{ position: "relative" }}>
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</ViewTouchableOpacity
</View>
}
/>
</View>
//styles
const styles = StyleSheet.create({
mainView: {
// devDims are the device dimensions
minHeight: devDims.height,
minWidth: devDims.width,
backgroundColor: "white",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
},
cartView: {
justifyContent: "center",
alignItems: "center",
maxHeight: 50,
minWidth: "100%",
alignSelf: "center",
marginTop: 50,
padding: 10,
borderRadius: 20,
},
cartText: {
fontFamily: "semi",
fontSize: 22,
},
});
We could handle this without absolute positioning using flex alone.
Add flex:1 to the parent view and to the view that wraps the sticky bottom. Then, add flex: 2 to the view that wraps the other content.
Here is a minimal generic component that lets you add a sticky bottom component.
const MainScreen = ({bottom, children}) => {
return <View style={{flex: 1, backgroundColor: 'red'}}>
<View style={{flex: 2, backgroundColor: 'green'}}>
{children}
</View>
<View style={{flex: 1, backgroundColor: 'yellow'}}>
{bottom}
</View>
</View>
}
export default function App() {
return <MainScreen bottom={
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</TouchableOpacity>}>
</MainScreen>
}
The result looks as follows:
However, we can use absolute positioning as well. You are just missing the flex: 1 for the parent view.
export default function App() {
return <View style={styles.mainView}>
<View style={{ position: "absolute", bottom: 0 }}>
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</TouchableOpacity>
</View>
</View>
}
const styles = StyleSheet.create({
mainView: {
flex: 1,
// devDims are the device dimensions
minHeight: devDims.height,
minWidth: devDims.width,
backgroundColor: "red",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
},
cartView: {
justifyContent: "center",
alignItems: "center",
maxHeight: 50,
minWidth: "100%",
backgroundColor: "yellow",
alignSelf: "center",
marginTop: 50,
padding: 10,
borderRadius: 20,
},
cartText: {
fontFamily: "semi",
fontSize: 22,
},
});
The result is as follows:
if you are using position as absolute then your view must be last view before last closed view tag
When you have declared any view at bottom of the screen then you should be do like this
import {View, SafeAreaView} from 'react-native';
<SafeAreaView style={{flex:1}}>
<View style={{flex:1}}>
<!---Anything extra views---!>
<View style={{bottom:0,position:'absolute',start:0,end:0}}> !-- you're bottom view
<TouchableOpacity style={styles.cartView}>
<Text style={styles.cartText}>View cart</Text>
</ViewTouchableOpacity
</View>
</View>
</SafeAreaView >
I have a react native project I am building. On the home screen I want to render a list of components called PropertyTile with some text in between just for testing. With my current code, it is rendering the first instance of the PropertyTile, but not rendering anything after that. It is extremely wierd and I can not find a solution to this issue for some reason. Why would it only show the first PropertyTile without rendering anything else.
Code:
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'
import PropertyTile from '../components/PropertyTile.js'
const HomeScreen = () => {
return (
<View style={styles.screenContainer}>
<PropertyTile/>
<Text>Home Screen: Shows currentl asdfasdf!</Text>
<Text>Home Screen: Shows currentl fe!</Text>
<PropertyTile />
</View>
)
}
const styles = StyleSheet.create({
header: {
fontSize: 22
},
screenContainer: {
display: 'flex',
flexDirection: 'column'
}
})
export default HomeScreen
current screen rendering
PropertyTile Code:
import React from 'react'
import { Dimensions } from 'react-native'
import { View, Text, StyleSheet, Image } from 'react-native'
export default function PropertyTile() {
let deviceWidth = Dimensions.get('window').width - 16
var aspectHeight = (deviceWidth / 1.78) + 1
return (
<View style={styles.container}>
<View style={[styles.imageContainer,{height: aspectHeight}]}>
<Image style={styles.mainImage} source={require('../../assets/luxury-home-1.jpeg')}/>
</View>
<View style={styles.contentContainer}>
<View style={styles.priceContainer}>
<Text style={styles.price}>$ 1,259,999</Text>
<Text style={styles.status}>For Sale</Text>
</View>
<View style={styles.addressContainer}>
<Text style={styles.address}>23 Lowlette Lane.</Text>
<Text style={styles.address}>Mission Viejo, CA 92692</Text>
</View>
<View style={styles.separator}></View>
<View style={styles.details}>
<Text style={styles.summary}>6 Beds | 6 Baths | 10,000 Sqft. | 1.3 acre Lot</Text>
<Text style={styles.homeType}>Single Family Residence</Text>
</View>
<View style={styles.separator}></View>
<View style={styles.details}>
<View style={styles.metricContainer}>
<Text style={styles.metricName}>Net Operating Income (Monthly): </Text>
<Text style={styles.metricValue}>$5,789</Text>
</View>
<View style={styles.metricContainer}>
<Text style={styles.metricName}>Cash on Cash Return: </Text>
<Text style={styles.metricValue}>2.45%</Text>
</View>
<View style={styles.metricContainer}>
<Text style={styles.metricName}>Return on Initial Investment: </Text>
<Text style={styles.metricValue}>9.97%</Text>
</View>
</View>
<View style={styles.disclaimerContainer}>
<Text style={styles.disclaimer}>*** 30 year fixed, 20% down, 3.14% interest rate | $3,443 rent ***</Text>
</View>
</View>
</View>
)
}
const styles = StyleSheet.create({
container: {
height: '100%',
paddingTop: 8,
paddingHorizontal: 8,
borderRadius: 6,
overflow: 'hidden'
},
imageContainer: {
width: '100%',
borderTopLeftRadius: 6,
borderTopRightRadius: 6,
overflow: 'hidden'
},
mainImage: {
width: '100%',
height: '100%'
},
contentContainer: {
width: '100%',
backgroundColor: '#D3D3D3',
borderBottomLeftRadius: 6,
borderBottomRightRadius: 6,
overflow: 'hidden',
paddingHorizontal: 8
},
priceContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingTop: 8,
},
price: {
fontWeight: 'bold',
fontSize: 24
},
addressContainer: {
display: 'flex',
marginTop: 8
},
address: {
fontSize: 14
},
separator: {
marginHorizontal: '3%',
marginVertical: 8,
height: 2,
width: '94%',
backgroundColor: 'grey'
},
homeType: {
marginTop: 4,
},
metricContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 4
},
metricValue: {
fontWeight: 'bold'
},
disclaimerContainer: {
display: 'flex',
flexDirection: 'row',
marginVertical: 8,
width: '100%',
justifyContent: 'center',
},
disclaimer: {
fontSize: 12,
}
})
I believe that your aspectHeight variable in your PropertyTile component is preventing the second instance from appearing. aspectHeight is applying a height that spans the height of the screen, pushing the other instances out of view.
You can try wrapping your HomeScreen in a ScrollView so you can see all of the elements that render below the screen's window, like this:
import React from 'react'
import { View, Text, StyleSheet, ScrollView } from 'react-native'
import PropertyTile from '../components/PropertyTile.js'
const HomeScreen = () => {
return (
<ScrollView>
<View style={styles.screenContainer}>
<PropertyTile/>
<Text>Home Screen: Shows currentl asdfasdf!</Text>
<Text>Home Screen: Shows currentl fe!</Text>
<PropertyTile />
</View>
</ScrollView>
)
}
I know similar questions have been asked before but I couldn't fix this myself. I have an icon and a text that should be displayed on both ends of the screen. The icon should be at the left end while the text should be at the right end.
However, the Text extends the screen and is hidden from the right side, even if I add marginRight or paddingRight. How can I fix this?
export default function App() {
return (
<SafeAreaView style={styles.safeAreaViewContainer}>
<View style={styles.container}>
<View style={styles.topTextContainer}>
<BackArrow containerStyles={styles.arrowContainer} arrowStyles={styles.arrow}></BackArrow>
<Text style={styles.allFavoritePlaces}>Alle Lieblingsorts</Text>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
arrowContainer: {
marginTop: 0,
marginBottom: 0,
marginLeft: 0,
},
arrow: {
color: 'black',
paddingTop: 0,
},
allFavoritePlaces: {
alignItems: 'flex-end',
paddingRight: moderateScale(0),
paddingBottom: moderateScale(10),
},
topTextContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginVertical: moderateScale(15),
height: moderateScale(30),
paddingHorizontal: 20,
},
});
Here's a codesandbox too: https://snack.expo.io/#nhammad/sponaneous-candy
I opend it in the dev tools. The container of your arrow has some width assigned to it, when the screen gets to small it pushes the text out of the viewport.
Hi i am a newbie in React Native, and trying to create an android app using the same. If i change the style of my view -> (backgroundColor or borrderBottom) it just doesn't render. There is no error anywhere, but on reloading the js bundle, the view and all its children fail to render. More than solving this particular issue, i am more interested in understanding why is this happening or whether i am missing something. My component in its entirety is below
import React from 'react';
import { StyleSheet, View, Text, PixelRatio, TextInput } from 'react-native';
const styles = {
container: {
paddingTop: 70,
flex: 1,
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: '#fff',
},
form: {
flex: 1,
flexDirection: 'column'
},
rowContainer: {
//backgroundColor: '#000',
},
row: {
flexDirection: 'row',
height: 44,
alignItems: 'center',
},
inputLabel: {
fontSize: 15,
paddingLeft: 15,
color: '#333'
},
textInputStyle: {
fontSize: 15,
flex: 1,
paddingLeft: 15
}
};
export default function TestComponent(props) {
return (
<View style={styles.container}>
<Text> Inside Container </Text>
<View style={styles.form}>
<Text> Inside Form </Text>
<View style={styles.rowContainer} >
<Text> Inside Row Container </Text>
<View style={styles.row}>
<Text numberOfLines={1} style={styles.inputLabel}> Bid On </Text>
<TextInput />
</View>
</View>
</View>
</View>
);
}
The above code works perfectly and all the components are rendered, however if i change the rowContainer style and uncomment backgroundColor, rowContainer and all its children are not rendered. I have no clue why this is happening. I also tried other styles inside rowContainer like
rowContainer: {
flex: 1,
flexDirection: 'column',
backgroundColor: '#000'
borderBottomWidth: 1,
borderColor: '#c8c7cc'
}
As long as rowContainer style is empty it works, if i add anything inside it, the view simply doesn't render.
The default Text color is black and the rowContainers backgroundColor is set to '#000'. So it appears as not being rendered.