Adding ImageBackground to React Native Login Screen - react-native

I found this great code sample/layout -- see below -- for a React Native login screen. All I want to do is to have an ImageBackground as opposed to the current solid background.
When I add ImageBackground to the code, it throws everything off and instead of the image covering the entire screen, everything gets squished in the middle and all alingment gets out of whack. What am I doing wrong here?
Here's the original code with solid background:
import React from 'react';
import { StyleSheet, Text, View, TextInput, TouchableOpacity } from 'react-native';
export default class App extends React.Component {
state={
email:"",
password:""
}
render(){
return (
<View style={styles.container}>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView} >
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({email:text})}/>
</View>
<View style={styles.inputView} >
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({password:text})}/>
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#003f5c',
alignItems: 'center',
justifyContent: 'center',
},
logo:{
fontWeight:"bold",
fontSize:50,
color:"#fb5b5a",
marginBottom:40
},
inputView:{
width:"80%",
backgroundColor:"#465881",
borderRadius:25,
height:50,
marginBottom:20,
justifyContent:"center",
padding:20
},
inputText:{
height:50,
color:"white"
},
forgot:{
color:"white",
fontSize:11
},
loginBtn:{
width:"80%",
backgroundColor:"#fb5b5a",
borderRadius:25,
height:50,
alignItems:"center",
justifyContent:"center",
marginTop:40,
marginBottom:10
},
loginText:{
color:"white"
}
});
This produces this nice layout:
And I simply add an image background with the following code which doesn't work at all:
<View style={styles.container}>
<ImageBackground
source={require("../../assets/images/background/teton_snake_dimmed.jpg")}
style={styles.imageBackground}
>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView} >
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({ email: text })} />
</View>
<View style={styles.inputView}>
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={text => this.setState({ password: text })} />
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</ImageBackground>
</View>
And here's the updated styles. The only thing I add is the imageBackground:
container: {
flex: 1,
backgroundColor: '#003f5c',
alignItems: 'center',
justifyContent: 'center',
},
logo: {
fontWeight: "bold",
fontSize: 50,
color: "#fb5b5a",
marginBottom: 40
},
imageBackground: {
flex: 1,
resizeMode: "cover"
},
inputView: {
width: "80%",
backgroundColor: "#465881",
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: "center",
padding: 20
},
inputText: {
backgroundColor: "#465881",
height: 50,
color: "white"
},
forgot: {
color: "white",
fontSize: 11
},
loginBtn: {
width: "80%",
backgroundColor: "#fb5b5a",
borderRadius: 25,
height: 50,
alignItems: "center",
justifyContent: "center",
marginTop: 40,
marginBottom: 10
},
loginText: {
color: "white"
}
});
What am I doing wrong here?
P.S. Here's the original code published by #Alhydra:
https://github.com/Alhydra/React-Native-Login-Screen-Tutorial/blob/master/App.js

Here is an example replace the image with the image you want
snack: https://snack.expo.io/#ashwith00/intelligent-banana
code:
import React from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Image,
} from 'react-native';
export default class App extends React.Component {
state = {
email: '',
password: '',
};
render() {
return (
<View style={styles.container}>
<Image
style={styles.image}
source={{
uri:
'https://media.gettyimages.com/videos/loopable-color-gradient-background-animation-video-id1182636595?s=640x640',
}}
/>
<View style={styles.subContainer}>
<Text style={styles.logo}>HeyAPP</Text>
<View style={styles.inputView}>
<TextInput
style={styles.inputText}
placeholder="Email..."
placeholderTextColor="#003f5c"
onChangeText={(text) => this.setState({ email: text })}
/>
</View>
<View style={styles.inputView}>
<TextInput
secureTextEntry
style={styles.inputText}
placeholder="Password..."
placeholderTextColor="#003f5c"
onChangeText={(text) => this.setState({ password: text })}
/>
</View>
<TouchableOpacity>
<Text style={styles.forgot}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginBtn}>
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.loginText}>Signup</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
image: {
flex: 1,
},
container: {
flex: 1,
backgroundColor: '#003f5c',
},
subContainer: {
...StyleSheet.absoluteFillObject,
alignItems: 'center',
justifyContent: 'center',
},
logo: {
fontWeight: 'bold',
fontSize: 50,
color: '#fb5b5a',
marginBottom: 40,
},
inputView: {
width: '80%',
backgroundColor: '#465881',
borderRadius: 25,
height: 50,
marginBottom: 20,
justifyContent: 'center',
padding: 20,
},
inputText: {
height: 50,
color: 'white',
},
forgot: {
color: 'white',
fontSize: 11,
},
loginBtn: {
width: '80%',
backgroundColor: '#fb5b5a',
borderRadius: 25,
height: 50,
alignItems: 'center',
justifyContent: 'center',
marginTop: 40,
marginBottom: 10,
},
loginText: {
color: 'white',
},
});

Related

Touchable Opacity not working when nested inside View component but works if Touchable opacity is made the parent component to wrap other components

I have the following component created for showing an image card on screen. Inside this card there is an image that I am trying to make touchable, however, its does seem to work and when I try clicking on it, nothing happens.
But if I make the Touchable opacity as a parent component below, then the complete image card component becomes touchable and it works on screen. However, I do not want that and only want to target sub elements in this below card component. Not sure how to fix this!
import React, { useState } from "react";
import {
View,
Image,
Text,
StyleSheet,
TouchableOpacity,
} from "react-native";
const ImageCardView = ({
title,
category,
Price,
description,
imageUrl,
rating,
}) => {
return (
<View style={{ backgroundColor: "#d3c4de" }}>
<View style={styles.cardContainer}>
<RedCircle />
<TouchableOpacity onPress={() => navigation.navigate("showCase")}>
<Image
source={{
uri: imageUrl,
}}
style={styles.image}
/>
</TouchableOpacity>
<SeparatorVertical />
<View style={styles.textContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.category}>{category}</Text>
<Text style={styles.price}>${Price}</Text>
<SeparatorHorizontal />
<Text numberOfLines={2} style={styles.description}>
{description}
</Text>
<View style={styles.rightBottom}>
<TouchableOpacity
style={styles.button}
onPress={() => setIsPressed(!isPressed)}
>
<Text>Add To Cart</Text>
</TouchableOpacity>
{/* {isPressed && (
<View
style={{
backgroundColor: "white",
paddingLeft: 16,
paddingRight: 16,
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
paddingBottom: 12,
}}
>
<TouchableOpacity
disabled={!items.length}
onPress={removeItemFromBasket}
>
<Icon
name="minus-circle"
size={40}
color={items.length > 0 ? "#00CCBB" : "gray"}
/>
</TouchableOpacity>
<Text>{items.length}</Text>
<TouchableOpacity onPress={addItemToBasket}>
<Icon name="plus-circle" size={40} color="#00CCBB" />
</TouchableOpacity>
</View>
</View>
)} */}
<View style={styles.ratingContainer}>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<Text
key={i}
style={[
styles.star,
ratingValue <= rating && styles.filledStar,
]}
>
★
</Text>
);
})}
</View>
</View>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
cardContainer: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "white",
borderRadius: 5,
overflow: "hidden",
marginVertical: 10,
marginLeft: 3,
width: "98%",
height: 300,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
image: {
width: 150,
height: 228,
resizeMode: "cover",
},
textContainer: {
paddingLeft: 10,
},
title: {
fontWeight: "bold",
fontSize: 20,
marginBottom: 10,
},
category: {
color: "#d6c3b9",
},
price: {
fontSize: 20,
fontWeight: "bold",
color: "#05c3fa",
},
description: {
flexDirection: "row",
flexWrap: "wrap",
fontSize: 15,
color: "#666",
marginBottom: 20,
},
ratingContainer: {
flexDirection: "row",
alignItems: "center",
},
button: {
alignItems: "center",
backgroundColor: "#5cb85c",
borderRadius: 5,
padding: 10,
},
rightBottom: {
flexDirection: "row",
},
star: {
fontSize: 18,
color: "#888",
},
filledStar: {
color: "#ffd700",
},
});
export default ImageCardView;
Without seeing the all the code, my suggestion is to make sure your TouchableOpacity is being imported from "react-native" and not from "react-native-gesture-handler" or some other npm package like "react-native-web".
Check the below code and logs, it's working fine:
import React, { useState } from "react";
import {
View,
Image,
Text,
StyleSheet,
TouchableOpacity,
} from "react-native";
const App = ({
title,
category,
Price,
description,
imageUrl,
rating,
}) => {
const [isPressed, setIsPressed] = useState(false)
return (
<View style={{ backgroundColor: "#d3c4de" }}>
<View style={styles.cardContainer}>
<TouchableOpacity onPress={() => {
console.log("on pressed!!!!")
navigation.navigate("showCase")
}
}>
<Image
source={{
uri: imageUrl,
}}
style={styles.image}
/>
</TouchableOpacity>
<View style={styles.textContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.category}>{category}</Text>
<Text style={styles.price}>${Price}</Text>
<Text numberOfLines={2} style={styles.description}>
{description}
</Text>
<View style={styles.rightBottom}>
<TouchableOpacity
style={styles.button}
onPress={() => {
console.log("Add to card pressed!!!!")
setIsPressed(!isPressed)
}}>
<Text>Add To Cart</Text>
</TouchableOpacity>
{isPressed && (
<View
style={{
backgroundColor: "white",
paddingLeft: 16,
paddingRight: 16,
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
paddingBottom: 12,
}}
>
<TouchableOpacity
disabled={!items.length}
onPress={removeItemFromBasket}
>
<Icon
name="minus-circle"
size={40}
color={items.length > 0 ? "#00CCBB" : "gray"}
/>
</TouchableOpacity>
<Text>{items.length}</Text>
<TouchableOpacity onPress={addItemToBasket}>
<Icon name="plus-circle" size={40} color="#00CCBB" />
</TouchableOpacity>
</View>
</View>
)}
<View style={styles.ratingContainer}>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<Text
key={i}
style={[
styles.star,
ratingValue <= rating && styles.filledStar,
]}
>
★
</Text>
);
})}
</View>
</View>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
cardContainer: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "white",
borderRadius: 5,
overflow: "hidden",
marginVertical: 10,
marginLeft: 3,
width: "98%",
height: 300,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
image: {
width: 150,
height: 228,
resizeMode: "cover",
},
textContainer: {
paddingLeft: 10,
},
title: {
fontWeight: "bold",
fontSize: 20,
marginBottom: 10,
},
category: {
color: "#d6c3b9",
},
price: {
fontSize: 20,
fontWeight: "bold",
color: "#05c3fa",
},
description: {
flexDirection: "row",
flexWrap: "wrap",
fontSize: 15,
color: "#666",
marginBottom: 20,
},
ratingContainer: {
flexDirection: "row",
alignItems: "center",
},
button: {
alignItems: "center",
backgroundColor: "#5cb85c",
borderRadius: 5,
padding: 10,
},
rightBottom: {
flexDirection: "row",
},
star: {
fontSize: 18,
color: "#888",
},
filledStar: {
color: "#ffd700",
},
});
export default App;
For navigation, you need to get it referenced from parent props.
Thanks everyone. I got it fixed, in my case somehow the component was blocking the Touchable opacity, so included that inside my Touchable capacity to include the with the image and it started working

I want to change the width of the KeyboardAvoidingView movement with custom TextInput

I am developing iOS apps in React Native Expo.
To display the image icon and placeholder in the Input column, I set it to Image icon and TextInput in the View.
When using KeyboardAvoidingView, the keyboard scrolls to the bottom of TextInput as shown in the attached image (1), but does anyone know if it is possible to scroll to the bottom of the description of the input field as shown in image (2)?
Image(1)
Image(2)
The article is based on the following.
https://reactnative.dev/docs/keyboardavoidingview
Parent function code.
<KeyboardAvoidingView behavior="padding" style={styles.containerStyle}>
<SafeAreaView style={styles.containerStyle}>
<ScrollView style={styles.containerStyle}>
<View style={styles.headContainerStyle}></View>
<View style={styles.mainContainerStyle}></View>
<View style={styles.headMessageContainerStyle}>
<Text style={styles.headMessageTextStyle}>Sign Up</Text>
</View>
{/* Email */}
<MailForm
inputAccessoryViewID={inputAccessoryViewID}
isCorrectMail={isCorrectMail}
setIsCorrectMail={setIsCorrectMail}
/>
{/* Password */}
<PasswordForm
inputAccessoryViewID={inputAccessoryViewID}
isCorrectPassewordSymbol={isCorrectPassewordSymbol}
setIsCorrectPassewordSymbol={setIsCorrectPassewordSymbol}
isCorrectPassewordStringCount={isCorrectPassewordStringCount}
setIsCorrectPassewordStringCount={setIsCorrectPassewordStringCount}
/>
{/* UserId */}
<UserIdForm
inputAccessoryViewID={inputAccessoryViewID}
isCorrectUserIdSymbol={isCorrectUserIdSymbol}
setIsCorrectUserIdSymbol={setIsCorrectUserIdSymbol}
isCorrectUserIdStringCount={isCorrectUserIdStringCount}
setIsCorrectUserIdStringCount={setIsCorrectUserIdStringCount}
isAvailableUserId={isAvailableUserId}
setIsAvailableUserId={setIsAvailableUserId}
/>
{/* Screen Bottom */}
<View style={styles.bottomStyle}>
{isCorrectMail && isCorrectPassewordSymbol && isCorrectPassewordStringCount && isCorrectUserIdSymbol && isCorrectUserIdStringCount && isAvailableUserId ?
(
<TouchableOpacity
style={styles.buttonContainerStyle}>
<Text style={styles.buttonTextStyle}>Sign Up</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={[styles.buttonContainerStyle, styles.buttonContainerInvalidStyle]}
onPress={() => navigation.navigate('SignUp')}>
<Text style={styles.buttonTextStyle}>Sign Up</Text>
</TouchableOpacity>
)}
<View style={styles.toLoginStyle}>
<Text style={styles.toLoginTextStyle}>Do you have an account?</Text>
<Text style={[styles.toLoginTextStyle, styles.toLoginTextLinkStyle]}>Login here</Text>
</View>
</View>
</ScrollView>
</SafeAreaView>
</KeyboardAvoidingView>
The code for the <UserId/> component, which we want to support scrolling for this time.
<View>
<View style={styles.searchBoxStyle}>
<View style={styles.searchWrapperStyle}>
<Pressable style={styles.searchContainerStyle} onPress={() => textInputUserId.focus()}>
<Text style={styles.searchTitleStyle}>UserId</Text>
{/* <KeyboardAvoidingView behavior="padding"> */}
<View style={defaultUserIdBorderColor ? isCorrectUserIdSymbol && isCorrectUserIdStringCount ? styles.searchViewStyle : [styles.searchViewStyle, styles.inputIncorrectBorderColorStyle]: styles.searchViewStyle}>
<Image source={require("../../../assets/profile.png")} style={styles.searchIconStyle}/>
{/* <KeyboardAvoidingView behavior="padding"> */}
<TextInput
onChangeText={onChangeUserIdText}
style={styles.searchContentStyle}
value={userIdText}
placeholder="test1234"
inputAccessoryViewID={inputAccessoryViewID}
ref={(input) => textInputUserId = input}
autoCapitalize="none"
maxLength={100}
textContentType="username"
onFocus={() => {
…
}}
onEndEditing={() => {
…
}}
/>
</View>
</Pressable>
</View>
</View>
{/* UserId Description */}
{displayUserIdDescription ? !isCorrectUserIdSymbol || !isCorrectUserIdStringCount || !isAvailableUserId ? (
<View style={styles.descriptionBoxStyle}>
<View style={styles.descriptionWrapperStyle}>
<View style={styles.descriptionContainerStyle}>
{!defaultDisplayUserIcons ? isCorrectUserIdSymbol ? <Image source={require("../../../assets/correct.png")} style={styles.descriptionIconStyle}/>: <Image source={require("../../../assets/incorrect.png")} style={styles.descriptionIconStyle}/>: null}
<Text style={styles.descriptionTextStyle}>Half-width alphanumeric characters only.</Text>
</View>
<View style={styles.descriptionContainerStyle}>
{!defaultDisplayUserIcons ? isCorrectUserIdStringCount ? <Image source={require("../../../assets/correct.png")} style={styles.descriptionIconStyle}/>: <Image source={require("../../../assets/incorrect.png")} style={styles.descriptionIconStyle}/>: null}
<Text style={styles.descriptionTextStyle} >More than 4 words and less than 100 words.</Text>
</View>
<View style={styles.descriptionContainerStyle}>
{!defaultDisplayUserIcons ? isAvailableUserId ? <Image source={require("../../../assets/correct.png")} style={styles.descriptionIconStyle}/>: <Image source={require("../../../assets/incorrect.png")} style={styles.descriptionIconStyle}/>: null}
<Text style={styles.descriptionTextStyle} >Available.</Text>
</View>
</View>
</View>
) : null: null}
</View>
Style sheet code.
import { StyleSheet } from 'react-native';
export const styles = StyleSheet.create({
containerStyle: {
flex: 1,
backgroundColor: "#1B1C56",
},
headContainerStyle: {
width: "100%",
height: "10%",
height: 40,
backgroundColor: "#1B1C56",
},
headMessageContainerStyle: {
backgroundColor: "#feffff",
alignItems: 'center',
},
headMessageTextStyle: {
fontSize: 50,
fontFamily: "AlfaSlabOne_400Regular",
color: "#1B1C56",
marginBottom: 32,
},
mainContainerStyle: {
width: "100%",
height: "15%",
backgroundColor: "#feffff",
borderTopLeftRadius: 50,
alignItems: 'center',
},
searchBoxStyle: {
flex: 1,
backgroundColor: "#feffff",
},
searchWrapperStyle: {
flex: 1,
alignItems: "center",
paddingBottom: 10,
},
searchContainerStyle: {
},
searchTitleStyle: {
fontFamily: "ABeeZee_400Regular_Italic",
color: "#262626",
marginBottom: 5,
},
searchIconStyle: {
width: 24,
height: 24,
marginRight: 10,
marginLeft: 10,
},
searchViewStyle: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#F6F7FB',
borderWidth: 0.5,
height: 60,
borderRadius: 5,
width: 300,
borderColor: "#F6F7FB",
},
searchContentStyle: {
flex: 1
},
inputIncorrectBorderColorStyle:{
borderWidth: 2,
borderColor: "#ED195E",
},
completeBoxStyle: {
width: 60,
alignItems: "center",
padding: 10,
},
completeTextStyle: {
fontSize: 18,
fontWeight: "bold",
color: "hsl(210, 100%, 60%)"
},
passwordIconStyle: {
marginRight: 10
},
descriptionBoxStyle:{
display: "flex",
alignItems: "center",
backgroundColor: "#feffff",
paddingBottom: 10,
},
descriptionWrapperStyle: {
},
descriptionContainerStyle: {
flexDirection: "row",
width: 300,
},
descriptionTextStyle: {
color: "#262626",
fontSize: 12,
overflow: "visible"
},
descriptionIconStyle:{
marginRight: 10,
width: 12,
height: 12,
},
bottomStyle: {
display: "flex",
alignItems: "center",
height: "100%",
backgroundColor: "#feffff",
},
buttonContainerStyle: {
alignItems: "center",
justifyContent: "center",
backgroundColor: "#1B1C56",
width: 300,
height: 60,
borderRadius: 10,
fontSize: 18,
},
buttonContainerInvalidStyle:{
backgroundColor: "#C5C5C7",
},
buttonTextStyle: {
color: "#feffff",
fontFamily: "ABeeZee_400Regular_Italic",
},
toLoginStyle: {
marginTop: 10,
height: "5%",
flexDirection: "row"
},
toLoginTextStyle: {
fontFamily: "ABeeZee_400Regular_Italic",
},
toLoginTextLinkStyle: {
color: "#ED195E",
marginLeft: 10,
},
});
Swapped the positions of KeyboardAvoidingView, SafeAreaView and ScrollView. I have tried to set the keyboardVerticalOffset and the keyboardVerticalOffset, but each had its own problems, and the current code was the closest to the ideal.

How to remove default left and right padding in react native

Image of Text.
Want to remove the left and right padding of forget password Text.Please Help
import React, { useState } from "react"
import { View, Text, SafeAreaView, Button, StyleSheet, TextInput, TouchableOpacity, Platform } from "react-native"
const Practice = (props) => {
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")
function onTappedLogIn() {
}
function onTappedForgetPass() {
}
function onTappedShow() {
}
return (
<SafeAreaView style={styles.containerView}>
<View style={styles.upperView}>
<TouchableOpacity>
<Text style={{ textDecorationLine: 'underline' }}>Sign Up</Text>
</TouchableOpacity>
</View>
<View style={styles.middleView}>
<Text style={[styles.text, { marginTop: 30 }]}>Email Address</Text>
<TextInput style={styles.textInput} onChangeText={(email) => setEmail(email)} />
<Text style={styles.text}>Password</Text>
<View style = {styles.passTextInputView}>
{/* <Text>Show</Text> */}
<TextInput style={styles.textInput} onChangeText={(pass) => { setPassword(pass) }} />
</View>
<TouchableOpacity style={styles.button} onPress={onTappedLogIn()}>
<View>
<Text style={styles.buttonText}>
Log In
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.forgetPass}>Forget Password?</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
containerView: {
flex: 1,
// justifyContent: 'center',
backgroundColor: 'grey'
},
middleView: {
flex: 0.45,
flexDirection: 'column',
backgroundColor: 'white',
marginLeft: 25,
marginRight: 25
},
upperView: {
flex: 0.30,
justifyContent: 'flex-start',
alignItems: 'flex-end',
marginRight: 15
},
text: {
marginLeft: 15,
marginTop: 15,
marginBottom: 20
},
textInput: {
borderBottomWidth: 1,
borderBottomColor: 'black',
marginLeft: 15,
marginRight: 15
},
button: {
padding: 15,
backgroundColor: 'green',
marginTop: 30,
marginLeft: 15,
marginRight: 15,
borderRadius: 25,
marginBottom: 20
},
buttonText: {
textAlign: "center",
fontWeight: 'bold',
color: 'white',
textDecorationLine: "underline"
},
forgetPass: {
textAlign: 'center',
textDecorationLine: 'underline',
includeFontPadding: false,
flex:0
},
passTextInputView:{
// flex:.3
}
})
export default Practice
Probably you need to set the text containers style to flex:0
Apply alignitems:'center' to the text container (sample)

React Native close Modal that is opened by different component

Hello I am fairly new to React Native and am currently having an issue with my modal component. My modal component has two props, gameData and isModalVisible. In Home.js modal prop isModalVisible has the value of a state variable isVisible that gets changed to true when a certain TouchableOpacity is pressed. Then inside my FeaturedGameModal.js isModalVisible is set from props. The issue I am having is closing the modal. Opening the modal this way works fine, but how should I close the modal since its visibility is being controlled by props that are in Home.js? Any help would be greatly appreciated. I have been working on this for two days now and it is driving me crazy. Thanks! I will include my two files in case you want to more closely inspect my code.
Home.js:
import React from 'react';
import {
View,
Text,
Image,
SafeAreaView,
TouchableOpacity,
ActivityIndicator,
Linking,
ScrollView,
TouchableHighlight,
} from 'react-native';
import {homeStyles} from '../styles/homeStyles';
import {styles} from '../styles/styles';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons';
import icoMoonConfig from '../../assets/fonts/selection.json';
import {fetchData} from '../functions/fetch';
import Modalz from '../modals/FeaturedGameModal';
const Icon = createIconSetFromIcoMoon(icoMoonConfig);
class Home extends React.Component {
myData = {};
constructor(props) {
super(props);
this.state = {
error: false,
isFetching: true,
featuredGameModal: false,
isVisible: false,
};
}
handleFeaturedGame = async () => {
this.setState({}, async () => {
try {
const featureGameData = await fetchData(
'http://dev.liberty.edu/templates/flames/json/json_appHomeFeed.cfm',
);
this.setState({
error: false,
featuredGameData: featureGameData,
isFetching: false,
});
} catch (e) {
this.setState({
error: true,
});
console.log(e.message);
}
});
};
handleFeaturedModal() {
this.setState({featuredGameModal: false});
}
componentDidMount() {
this.handleFeaturedGame();
}
render() {
const {featuredGameData} = this.state;
return this.state.isFetching ? (
<View style={styles.center}>
<ActivityIndicator size="large" color="#AE0023" />
</View>
) : (
<ScrollView>
<SafeAreaView>
<View style={homeStyles.featuredGameContainer}>
<View style={homeStyles.centerHor}>
<Image
style={homeStyles.logo}
source={require('../../assets/images/FlamesLogo.png')}
/>
</View>
<View style={homeStyles.gameTimeContainer}>
<Text style={homeStyles.gameTime}>
{featuredGameData.featuredGame.eventdate}
</Text>
<Text style={homeStyles.gameTime}>
{featuredGameData.featuredGame.eventtime}
</Text>
</View>
<TouchableOpacity
activeOpacity={0.6}
onPress={() => {
this.setState({isVisible: true});
}}>
<View style={homeStyles.contentContainer}>
<View style={homeStyles.contentLeft}>
<Text style={homeStyles.teamText}>
{featuredGameData.featuredGame.teamname}
</Text>
<Text style={homeStyles.opponentText}>
vs {featuredGameData.featuredGame.opponent}
</Text>
<Text style={homeStyles.locationText}>
<Icon size={12} name={'location'} />
{featuredGameData.featuredGame.location}
</Text>
</View>
<View style={homeStyles.contentRight}>
<Image
style={homeStyles.opponentLogo}
source={{
uri: featuredGameData.featuredGame.OpponentLogoFilename,
}}
/>
</View>
</View>
</TouchableOpacity>
<View style={homeStyles.allContent}>
<Modalz
gameData={this.state.featuredGameData.featuredGame}
isModalVisible={this.state.isVisible}
/>
<View style={homeStyles.contentContainerBottom}>
<View style={homeStyles.contentLeft}>
<TouchableOpacity
style={homeStyles.buyTicketBtn}
onPress={() =>
Linking.openURL(featuredGameData.featuredGame.buyTickets)
}>
<Text style={homeStyles.buyTicketBtnText}>Buy Tickets</Text>
</TouchableOpacity>
</View>
<View style={homeStyles.liveContainer}>
<Text style={homeStyles.live}>Experience Live:</Text>
<View style={homeStyles.liveIconsContainer}>
<Icon
style={{color: '#FFF', marginRight: 4}}
size={15}
name={'radio'}
/>
<Icon style={{color: '#FFF'}} size={12} name={'LFSN'} />
</View>
</View>
</View>
</View>
</View>
<View style={homeStyles.newsContainer}>
{featuredGameData.News.map((item, key) => (
<View
key={key}
style={[homeStyles.centerHor, homeStyles.newsCard]}>
<Image
style={homeStyles.newsImage}
source={{
uri: item.Thumbnail,
}}
/>
<Text style={homeStyles.headline}>{item.Headline}</Text>
<View style={homeStyles.teamNameView}>
<Text style={homeStyles.teamNameText}>{item.teamname}</Text>
<Text>{item.GameDate}</Text>
</View>
</View>
))}
</View>
</SafeAreaView>
</ScrollView>
);
}
}
export default Home;
FeaturedGameModal.js:
import React from 'react';
import {
Alert,
Modal,
StyleSheet,
Text,
TouchableHighlight,
View,
Image,
Dimensions,
TouchableOpacity,
SafeAreaView,
} from 'react-native';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons';
import icoMoonConfig from '../../assets/fonts/selection';
import {homeStyles} from '../styles/homeStyles';
const Icon = createIconSetFromIcoMoon(icoMoonConfig);
const windowWidth = Dimensions.get('window').width;
export default class Modalz extends React.Component {
constructor(props) {
super(props);
this.state = {
teamName: props.gameData.teamname,
opponentName: props.gameData.opponent,
eventDate: props.gameData.eventdate,
liveAudioURL: props.gameData.LiveAudioURL,
liveStatsURL: props.gameData.LiveStatsURL,
videoURL: props.gameData.VideoURL,
opponentLogoURL: props.gameData.OpponentLogoFilename,
};
}
render() {
const {
opponentName,
teamName,
eventDate,
opponentLogoURL,
liveStatsURL,
liveAudioURL,
videoURL,
location,
} = this.state;
const {isModalVisible} = this.props;
return (
<View>
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={isModalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<SafeAreaView style={{flex: 1, backgroundColor: 'transparent'}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Icon
style={styles.closeButton}
size={25}
name={'x'}
onPress={() => {}}
/>
<Text style={styles.upcomingGameTitle}>
{teamName} vs {opponentName}
</Text>
<Text style={styles.upcomingGameSubtitle}>{eventDate}</Text>
<View style={styles.facingLogosBlock}>
<View style={styles.leftTeamBlock} />
<View style={styles.rightTeamBlock} />
<View style={styles.vsTextWrapper}>
<Text style={styles.vsText}>VS</Text>
</View>
<View style={styles.logoWrapper}>
<Image
style={styles.facingLogoImg}
source={{
uri:
'https://www.liberty.edu/templates/flames/images/flamesMonogram.png',
}}
/>
<Image
style={styles.facingLogoImg}
source={{uri: opponentLogoURL}}
/>
</View>
</View>
<View>
<TouchableOpacity style={styles.buyTicketBtn}>
<Text style={styles.buyTicketBtnText}>Buy Tickets</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity
style={{...styles.iconButton, ...styles.iconButtonLeft}}>
<Icon
style={styles.iconButtonIcon}
size={25}
name={'flag'}
onPress={() => {
this.toggleModal(!this.state.modalVisible);
}}
/>
<Text style={styles.iconButtonText}>Game Day</Text>
</TouchableOpacity>
<TouchableOpacity
style={{...styles.iconButton, ...styles.iconButtonRight}}>
<Icon
style={styles.iconButtonIcon}
size={25}
name={'stats'}
onPress={() => {
this.toggleModal(!this.state.modalVisible);
}}
/>
<Text style={styles.iconButtonText}>Live Stats</Text>
</TouchableOpacity>
</View>
<View style={styles.liveLinkBlock}>
<View style={styles.liveLinkLeft}>
<Icon
style={styles.iconButtonIcon}
size={18}
name={'LFSN'}
/>
<Text>The Journey 88.3 FM</Text>
</View>
<TouchableOpacity style={styles.liveButton}>
<Text style={styles.liveButtonText}>Listen Live</Text>
</TouchableOpacity>
</View>
<View style={styles.liveLinkBlock}>
<View style={styles.liveLinkLeft}>
<Icon
style={styles.iconButtonIcon}
size={18}
name={'espn3'}
/>
<Text>LFSN TV Production</Text>
</View>
<TouchableOpacity style={styles.liveButton}>
<Text style={styles.liveButtonText}>Watch Live</Text>
</TouchableOpacity>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalView: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: 'white',
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: 14,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
openButton: {
backgroundColor: '#F194FF',
borderRadius: 20,
padding: 10,
elevation: 2,
},
closeButton: {
position: 'absolute',
right: 16,
top: 16,
color: '#000',
},
closeText: {
color: '#000',
fontWeight: 'bold',
textAlign: 'center',
fontSize: 20,
},
upcomingGameTitle: {
color: '#19191A',
fontSize: 18,
fontWeight: 'bold',
},
upcomingGameSubtitle: {
color: '#747676',
fontSize: 13,
fontWeight: 'bold',
marginBottom: 16,
},
modalText: {
marginBottom: 15,
textAlign: 'center',
},
facingLogosBlock: {
flexDirection: 'row',
position: 'relative',
alignItems: 'center',
},
facingLogoImg: {
width: 100,
height: 100,
resizeMode: 'contain',
flex: 1,
},
leftTeamBlock: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderRightWidth: 35,
borderTopWidth: 185,
borderRightColor: 'transparent',
borderTopColor: '#AE0023',
borderLeftColor: '#AE0023',
borderLeftWidth: windowWidth / 2,
left: 15,
zIndex: -1,
position: 'relative',
},
rightTeamBlock: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderLeftWidth: 35,
borderBottomWidth: 185,
borderBottomColor: '#461964',
borderRightColor: '#461964',
borderLeftColor: 'transparent',
borderRightWidth: windowWidth / 2,
right: 15,
zIndex: -1,
position: 'relative',
},
vsTextWrapper: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
},
vsText: {
color: '#000000',
backgroundColor: '#FFFFFF',
padding: 5,
fontWeight: 'bold',
},
logoWrapper: {
position: 'absolute',
width: windowWidth,
height: 185,
top: 0,
left: 35,
flexDirection: 'row',
alignItems: 'center',
},
buyTicketBtn: {
marginTop: 24,
backgroundColor: '#AE0023',
borderRadius: 4,
paddingVertical: 20,
paddingHorizontal: 12,
width: windowWidth - 24,
},
buyTicketBtnText: {
fontSize: 21,
color: '#fff',
fontWeight: 'bold',
alignSelf: 'center',
textTransform: 'uppercase',
},
buttonRow: {
paddingVertical: 24,
paddingHorizontal: 12,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
iconButton: {
backgroundColor: '#F0F3F5',
borderRadius: 4,
paddingVertical: 14,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
flex: 1,
},
iconButtonText: {
color: '#19191A',
fontWeight: 'bold',
fontSize: 16,
marginLeft: 10,
},
iconButtonIcon: {
color: '#000',
},
iconButtonLeft: {
marginRight: 6,
},
iconButtonRight: {
marginLeft: 6,
},
liveLinkBlock: {
padding: 12,
borderStyle: 'solid',
borderTopColor: '#F0F3F5',
borderTopWidth: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
},
liveButton: {
backgroundColor: '#F0F3F5',
borderRadius: 4,
paddingVertical: 14,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
liveButtonText: {
color: '#19191A',
fontWeight: 'bold',
fontSize: 16,
},
liveLinkLeft: {
flex: 2,
},
});
You should create hideModal function in Home.js then pass it to Modalz component.
In Home.js, add this function:
hideModalz = () => {
this.setState({isVisible: true});
}
And pass this function to Modalz props:
<Modalz
gameData={this.state.featuredGameData.featuredGame}
isModalVisible={this.state.isVisible}
hide={hideModalz}
/>
In Modalz, call this.props.hide(); if you want to hide modal.

React Native KeyboardAvoidigView does not work with SafeAreaView

KeyboardAvoidingView does not seem to be working properly with SafeAreaView and not sure where is the issue come from.
Can anyone help me find the issue?
<SafeAreaView style={styles.safeArea}>
<View style={styles.viewStyle}>
<Text
style={styles.goBackText}
onPress={() => {this.props.navigation.goBack()}}><Ionicons name="md-arrow-round-back" size={28} /></Text>
{/* TODO: KeyboardAvoidingView does not work properly */}
<KeyboardAvoidingView behavior="padding" enabled>
<View style={styles.formView}>
<TextInput
style={styles.textInput}
placeholder="Email"
onChangeText={(email) => this.props.screenProps[1](email) }
/>
<TextInput
style={styles.textInput}
placeholder="Password"
secureTextEntry={true}
onChangeText={(password) => this.props.screenProps[2](password) }
/>
<TouchableOpacity style={styles.btnStyle} onPress={this.userLoginClicked}>
<Text style={styles.btnText}>Login</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</View>
</SafeAreaView>
const styles = StyleSheet.create({
safeArea: {
flex:1,
backgroundColor: '#eee'
},
viewStyle: {
flex:1,
justifyContent: 'center',
backgroundColor: '#eee'
},
goBackText: {
position: 'absolute',
top: 10,
left: 16
},
formView: {
padding: 16,
},
textInput: {
padding: 14,
backgroundColor: '#fff',
marginBottom: 10
},
btnStyle: {
padding: 14,
marginBottom: 10,
backgroundColor: '#fc0f82',
},
btnText: {
textAlign: 'center',
fontSize: 18,
color: '#f8f8f8'
},
errorText: {
color: '#ff0000',
marginBottom: 10
}
})