I am new to react native. I tried to change the background view on the container seems like it doesn't work. I attached the codes below.
Could anyone here tell me what is wrong with the code below?
const HomeScreen = () => {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1, backgroundColor: '#FF0000' }}>
<Text style={{
color: COLORS.Text,
marginLeft: 14,
marginTop: 16,
width: 100,
height: 20
}}>Hello world</Text>
</View>
</SafeAreaView>
);
Check the below code:
import React from 'react';
import {StyleSheet, Text, SafeAreaView } from 'react-native';
const App = () => {
return (
<SafeAreaView style={styles.container}>
<Text style={styles.text}>Page content</Text>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor:'green'
},
text: {
fontSize: 25,
fontWeight: '500',
},
});
export default App;
For more information, you can explore SafeArea Documentation.
I want to have this same style FlatList on small and big device.
In smaller screen I have perfectly white color between a item within this List, but on the bigger device, I don't see this white color.
How to fix it ?
my FlatList
const placeList = props => {
return (
<FlatList
style={styles.listContainer}
data={props.placesList}
renderItem={(info) => (
<ListItem
placeName={info.item.name}
placeImage={info.item.image}
onItemPressed={() =>
props.onItemSelected(info.item.key)}
/>
)}
/>
);
};
const styles = StyleSheet.create({
listContainer: {
width: "100%",
}
});
and here my ListItem
const listItem = (props) => (
<TouchableOpacity onPress={props.onItemPressed}>
<View style={styles.listItem}>
<Image
resizeMode="contain"
source={props.placeImage}
style={styles.placeImage}
/>
<Text>{props.placeName}</Text>
</View>
</TouchableOpacity>
);
const styles = StyleSheet.create({
listItem: {
width: "100%",
marginBottom: 5,
padding: 10,
backgroundColor: "#eee",
flexDirection: "row",
alignItems: "center"
},
placeImage: {
marginRight: 8,
height: 30,
width: 30
}
});
This is how it looks (5,10' vs 7') :
click 5,10' size
click 7,0' size
Try dimension props like width:dimension.get('screen or window ').Width you can use same property for height just change props height or width and
U can also add width:dimension.get('screen or window ').Width/2 like this.. U can customize that and that view can be adjust itself on different screens....
I just wanted to add an <ImageBackground> to my React Native project, but I always get the error message: "TypeError: undefined is not an object (evaluating style.width)". Error located at ImageBackground (at index.js:31).
I have another project where it works perfectly like this. Could it be a problem of the React Native version?
import React, {Component} from 'react'
import {
StyleSheet,
View,
TouchableOpacity,
Text,
AsyncStorage,
Dimensions,
ImageBackground
} from 'react-native'
import * as Colors from '../../themes/colors'
import {getNavigationOptions} from '../../utils/navigation'
import * as ducks from '../../ducks'
import {connect} from 'react-redux'
class LoginScreen extends Component{
login(){
const {updateCurrentUser} = this.props
updateCurrentUser({name: 'Mauricio'})
console.log('login', this.props.currentUser)
}
olvidarContraseña(){
console.log('olvidar contraseña')
}
render(){
return (
<View style={styles.container}>
<View style={[styles.input, {borderColor: Colors.primary}]}>
<ImageBackground>
style={styles.backgroundImage}
source={require('./trigo_background.jpg')}>
{/* <TouchableOpacity
style={styles.btnSubmit}
onPress={() => this.login()}
>
<Text style={{textAlign: 'center', color: Colors.primary}}>
Iniciar Sesión
</Text>
</TouchableOpacity> */}
</ImageBackground>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
backgroundImage: {
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
position: 'absolute',
top: 0,
left: 0
},
btnSubmit: {
justifyContent: 'center',
padding: 10,
flexDirection: 'row'
},
input: {
height: 40,
paddingHorizontal: 10,
borderWidth: 1,
borderRadius: 5
}
})
LoginScreen.navigationOptions = ({navigation}) =>
getNavigationOptions('Login', Colors.primary, 'white')
const mapStateToProps = store => ({
currentUser: store.currentUser
})
const mapDispatchToProps = {
updateCurrentUser: ducks.updateCurrentUser
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen)
The error is in your code snippet
<ImageBackground> <== Here
style={styles.backgroundImage}
source={require('Valcereal/assets/trigo_background.jpg')}>
{/* <TouchableOpacity
style={styles.btnSubmit}
onPress={() => this.login()}
>
<Text style={{textAlign: 'center', color: Colors.primary}}>
Iniciar Sesión
</Text>
</TouchableOpacity> */}
</ImageBackground>
You've closed the tag and adding lines of code after it which would throw an error since it is not valid jsx
The correct code is
<ImageBackground
style={styles.backgroundImage}
source={require('Valcereal/assets/trigo_background.jpg')}>
{/* <TouchableOpacity
style={styles.btnSubmit}
onPress={() => this.login()}
>
<Text style={{textAlign: 'center', color: Colors.primary}}>
Iniciar Sesión
</Text>
</TouchableOpacity> */}
</ImageBackground>
At the top of your file destructor the height and width property like
const { width, height } = Dimensions.get('window');
In our styles object replace BackgroundImage object with
backgroundImage: {
width: width,
height: height,
position: 'absolute',
top: 0,
left: 0
},
Another alternative to setting a backgroundImage in React native is to set the height and width to 100%.
backgroundImage: {
width: 100%,
height: 100%,
},
Despite the wrong format you have provided, you'll also get the same results/error.
so the style of ImageBackground should be like this:
{ width: undefined, height: undefined }
Provided in the doc's of react-native ImageBackground
I'm trying to set a background image in react native.I want a background cover image. I've done like the below
<ScrollView>
<View>
<Image source={ require('../Images/5.jpg') } style = { styles.image } />
{
this.state.details.map(a =>
<View>
<Text style={ styles.textStyle } > { a.content = a.content.replace(regex, '') } < /Text>
< RadioForm style= {{ width: 350 - 30 }} outerColor = "#080103" innerColor = "#FF5733" itemShowKey = "label" itemRealKey = "item" dataSource = { transform(a.options) } onPress = {(item)=>this._onSelect(item)}/>
</View>)
}
</View>
</ScrollView>
const styles = StyleSheet.create({
image: {
flex: 1,
resizeMode: 'cover',
position: 'absolute',
width: "100%",
flexDirection: 'column'
},
textStyle: {
fontSize: 16,
color: '#000',
padding: 5,
},
});
But I'm getting something like this
You might need to add the ImageBackground outside of your ScrollView and make sure flex is being passed to the ImageBackground style'
For example
<View style={{flex: 1}}>
<ImageBackground
resizeMode={'stretch'} // or cover
style={{flex: 1}} // must be passed from the parent, the number may vary depending upon your screen size
source={require('/*Your Image Path*/')}
>
<ScrollView>
{/*Render the children here*/}
</ScrollView>
</ImageBackground>
</View>
What you need is ImageBackgroundcomponent.
import {ImageBackground} from 'react-native';
<ImageBackground
source={require('./pathToYourImage.png')}
style={yourCustomStyle}>
</ImageBackground>
That should do it.
import React from 'react';
import { View, Image, StyleSheet } from 'react-native';
import { WINDOW } from '../assets/config.js';
class Splash extends React.Component{
render(){
return(
<View style={styles.splashContainer}>
<Image
style={styles.bgImage}
source={require('../assets/images/splash.jpg')}
/>
</View>
)
}
}
const styles = StyleSheet.create({
splashContainer: {
flex: 1
},
bgImage: {
flex: 1,
width: WINDOW.width,
height: WINDOW.height,
}
});
export default Splash;
try like this. This worked fine for me.
Use
<ImageBackground
source={your image path}>
I have a View with few form elements and a button (TouchableHighlight). On clicking the button, an Activity Indicator should be shown as an overlay to the existing view. The Activity Indicator should be centered within the page and the existing view should be slightly blurred to indicate overlay. I tried different options but could not get it to work.
render() {
const { username, password } = this.state;
return (
<View style={styles.container}>
<View style={styles.group}>
<Text style={styles.text}>Username:</Text>
<TextInput
style={styles.input}
onChangeText={this.handleUserNameChange.bind(this)}
value={username}
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.group}>
<Text style={styles.text}>Password:</Text>
<TextInput
style={styles.input}
secureTextEntry={true}
onChangeText={this.handlePasswordChange.bind(this)}
value={password}
underlineColorAndroid="transparent"
/>
</View>
<TouchableHighlight
style={styles.button}
onPress={this.handleLogin.bind(this)}>
<Text style={styles.buttonText}>Logon</Text>
</TouchableHighlight>
</View>
);
}
Existing styles:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#F5FCFF',
marginTop: 60
},
group: {
alignItems: 'flex-start',
padding: 10
},
input: {
width: 150,
padding: 2,
paddingLeft: 5,
borderColor: 'gray',
borderWidth: 1
},
text: {
padding: 0
},
button: {
width: 150,
backgroundColor: '#2299F2',
padding: 15,
marginTop: 20,
borderRadius: 5
},
buttonText: {
textAlign: 'center',
color: '#fff',
fontSize: 24
},
});
I need to an ActivityIndicator to the above View, overlay the view, and center the ActivityIndicator.
For this to work, you'd need to absolute position it, and render it after the elements that should be underneath the overlay:
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
}
Then simply compose it into the render method conditionally, based on a loading state. I am going to assume this.handleLogin sets some sort of loading state already.
Make sure it's rendered last so it takes precedence.
...
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator size='large' />
</View>
}
Here is a complete example using create react native app.
import React from 'react';
import {StyleSheet, ActivityIndicator, View} from "react-native";
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {}
render() {
return (
<View
style={{flex: 1}}
>
//Add other content here
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator/>
</View>
}
</View>
);
}
}
showLoading() {
this.setState({loading: true})
}
hideLoading() {
this.setState({loading: false})
}
const styles = StyleSheet.create({
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.5,
backgroundColor: 'black',
justifyContent: 'center',
alignItems: 'center'
}
})
You can use StyleSheet.absoluteFill to shorten code.
Add this to your render:
<View style={styles.container}>
//... other code here
{this.state.loading && <View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator />
</View>}
</View>
Improvement:
You can also create a Loading component:
Loading.js
import React from 'react';
import {View, ActivityIndicator, StyleSheet} from 'react-native';
export const Loading = ({theme = 'white', size = 'large'}) => {
const color = theme === 'white' ? '#00bdcd' : '#fff';
return (
<View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator size={size} color={color} />
</View>
);
};
Then use it anywhere you want
<View style={styles.container}>
//... other code here
// remember to import Loading component
{this.state.loading && <Loading />}
</View>
You can build a nice overlay using the activity indicator component by also leveraging the modal capabilities like Sanaur suggests.
For example you can use the below functional component. You can control it's visibility through the show prop that you can tie to a state in your screen.
An example that you can adapt to your needs.
const ModalActivityIndicator = props => {
const {
show = false,
color = "black",
backgroundColor = "white",
dimLights = 0.6,
loadingMessage = "Doing stuff ..."
} = props;
return (
<Modal transparent={true} animationType="none" visible={show}>
<View
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: `rgba(0,0,0,${dimLights})`
}}
>
<View
style={{
padding: 13,
backgroundColor: `${backgroundColor}`,
borderRadius: 13
}}
>
<ActivityIndicator animating={show} color={color} size="large" />
<Text style={{ color: `${color}` }}>{loadingMessage}</Text>
</View>
</View>
</Modal>
);
};
and in your screen, in the render's return, just add it there as a child (please ignore the rest of the code, I put it there for context).
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={{ padding: 13, flex: 1}}>
<ModalActivityIndicator show={screenIsWaiting} />
<View
style={{
where screenIsWaiting is just a state, for example
const [screenIsWaiting, setScreenIsWaiting] = useState(false);
To test it you can add a button somewhere,
<Button
title="TestButton"
onPress={async () => {
setScreenIsWaiting(true);
await sleep(5000);
setScreenIsWaiting(false);
...
}}
/>
where sleep is a function defined as
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
I found the sleep() idea on stackoverflow on another post.
You can of course also define the
<ModalActivityIndicator show={screenIsWaiting} ... />
only once in your App's root component and trigger it's display and props via a global state container like redux.
There is a library available for this react-native-loading-spinner-overlay.
You can simply install it using
npm install react-native-loading-spinner-overlay --save
and can import into your project using
import Spinner from 'react-native-loading-spinner-overlay';
Here is how to use it
<Spinner
//visibility of Overlay Loading Spinner
visible={this.state.loading}
//Text with the Spinner
textContent={'Loading...'}
//Text style of the Spinner Text
textStyle={styles.spinnerTextStyle}
/>
STEP 1:
Create the component for the spinner:
export const OverlaySpinner = () => {
return (
<View style={styles.spinnerView}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
};
STEP 2:
Create the style for the spinner view (using zIndex is very important to make sure the view is over everything on the screen):
spinnerView: {
position: "absolute",
zIndex: 1,
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#F5FCFF88",
},
STEP 3:
Make the initial state for the spinning component:
const [showSpinner, setshowSpinner] = useState(true);
STEP 4:
Use the component and don't forget to import it (don't forget to dismiss the keyboard on submit)
{showSpinner && <OverlaySpinner />}
I suppose you should use Modal to overlay activity indicator. Following is an example:
<Modal
transparent={true}
animationType={'none'}
visible={loading}
onRequestClose={() => {console.log('close modal')}}>
<View style={styles.modalBackground}>
<View style={styles.activityIndicatorWrapper}>
<ActivityIndicator
animating={loading} />
</View>
</View>
</Modal>
Add in view of loading
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
set in View of Activity Indicator
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
Here my code for a functional component for anyone looking to achieve this with nativebase as design system. useColorScheme is another hook I use for detecting dark mode.
import { Flex, Spinner } from "native-base"
import React from "react"
import useColorScheme from "../../hooks/useColorScheme"
export default function Loading() {
const colorScheme = useColorScheme()
return (
<Flex
position="absolute"
alignItems="center"
justifyContent="center"
top={0}
left={0}
right={0}
bottom={0}
backgroundColor={colorScheme === "dark" ? "coolBlack.500" : "white"}
>
<Spinner size="lg" color={colorScheme === "dark" ? "white" : "coolBlack.500"} />
</Flex>
)
}