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.
Related
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 need to show different tags depending on which user is logged.
Franchisee will see: 'Central' 'Empleados' 'Clientes'.
Employee: 'Store' 'Clientes'
User: none. just the generic info.
Here is my code:
(this is the array that states the scrollview)
const Chats = (props) => {
const TAGS = [
"store",
"Clientes",
"Central",
"Empleados",
]
and this is the component:
import React, { useState } from "react";
import { StyleSheet, FlatList, TouchableOpacity, ScrollView, Image } from 'react-native';
import { SimpleHeader, View, Text } from '../../elements/index';
const Chatstores = ({ chatsstore, navigation }) => (
<View>
<TouchableOpacity onPress={() => navigation.navigate("ChatPersonal")}>
<View style={styles.list} >
<Image source={chatsstore.img} style={styles.iconimg} />
<View style={styles.dataText}>
<View style={styles.nametime}>
<Text style={styles.text}>{chatsstore.name} </Text>
<Text >{chatsstore.time}</Text>
</View>
<Text style={styles.msg}>{chatsstore.msg} </Text>
</View>
</View>
</TouchableOpacity>
</View>
);
const ChatClients = ({ chatsClients, navigation }) => (
<View>
<TouchableOpacity onPress={() => navigation.navigate("ChatPersonal")}>
<View style={styles.list}>
<Image source={chatsClients.img} style={styles.iconimg} />
<View style={styles.dataText}>
<View style={styles.nametime}>
<Text style={styles.text}>{chatsClients.name} </Text>
<Text >{chatsClients.time}</Text>
</View>
<Text style={styles.msg}>{chatsClients.msg} </Text>
</View>
</View>
</TouchableOpacity>
</View>
);
const Chats = (props) => {
const { TAGS, chatsstore, chatsClients, navigation } = props;
const [selectedTag, setSelectedTag] = useState(null)
const [routeDistance, setRouteDistance] = useState(0);
return (
<View style={styles.wrapper}>
<SimpleHeader
style={styles.head}
titleLeft="Chats"
onSearchPress
onAddPress
/>
{/**shows horizontal, scrollview of Tags. */}
<View style={styles.scrollview}>
<ScrollView horizontal showsHorizontalScrollIndicator={false} >
<View style={styles.viewcontainer}>
{TAGS.map((tag) => (
<TouchableOpacity
onPress={() =>
setSelectedTag(tag === selectedTag ? null : tag)
}>
<View
style={[
styles.tag,
selectedTag === tag ? styles.selectedTag : {}
]}>
<Text style={styles.textTag}>{tag}</Text>
</View>
</TouchableOpacity>
))}
</View>
</ScrollView>
</View>
{/**If tag is store, shows its data, otherwise the rest */}
{selectedTag === "store" ? (
<View style={styles.chat}>
<FlatList
data={chatsstore}
renderItem={({ item, index }) => (
<Chatstores
chatsstore={item}
index={index}
navigation={navigation}
/>
)}
keyExtractor={(chatsstore) => chatsstore.name}
ListEmptyComponent={() => (
<Text center bold>No hay ningún mensaje de clientes</Text>
)}
/>
</View>
) :
<View style={styles.chat}>
<FlatList
data={chatsClients}
renderItem={({ item, index }) => (
<ChatClients
chatsClients={item}
index={index}
navigation={navigation}
/>
)}
keyExtractor={(chatsClients) => chatsClients.name}
ListEmptyComponent={() => (
<Text center bold>No hay ningún mensaje de clientes</Text>
)}
/>
</View>
}
</View>
);
};
const styles = StyleSheet.create({
wrapper: {
backgroundColor: "#ffffff",
display: "flex",
flex: 1,
},
head: {
height: 80,
display: "flex",
alignItems: "center",
zIndex: 1,
top: 5,
},
scrollview: {
display: "flex",
alignItems: "center",
justifyContent: "space-evenly",
},
viewcontainer: {
display: "flex",
flexDirection: "row",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 1,
right: 10,
},
list: {
bottom: 15,
flexWrap: "wrap",
alignContent: "space-between",
position: "relative",
marginVertical: 2,
backgroundColor: "#fff",
shadowColor: "#000",
elevation: 2,
flexDirection: "row",
}, dataText: {
alignSelf: "center",
flexDirection: "column",
width: "80%",
},
nametime: {
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
},
iconimg: {
display: "flex",
height: 43,
width: 43,
alignSelf: "center",
flexDirection: "column",
},
chat: {
margin: 10,
},
text: {
margin: 10,
fontFamily: "Montserrat_700Bold",
paddingHorizontal: 10,
},
msg: {
margin: 10,
fontFamily: "Montserrat_400Regular",
fontSize: 15,
paddingHorizontal: 10,
bottom: 10
},
map: {
display: "flex",
height: "100%",
},
tag: {
display: "flex",
alignSelf: "center",
marginBottom: 1,
width: 225,
padding: 10,
},
selectedTag: {
borderBottomColor: '#F5BF0D',
borderBottomWidth: 2,
},
textTag: {
fontFamily: "Montserrat_700Bold",
alignItems: "center",
textAlign: "center",
fontSize: 15,
},
buttonContainer: {
marginHorizontal: 20
},
button: {
backgroundColor: "#000000",
top: Platform.OS === 'ios' ? 12 : 20,
height: 60,
marginBottom: 40,
marginRight: 10,
},
});
export default Chats;
So I guess that in my "show horizontal tags" I should write some kind of if, that gets the role from the user token?
Or would it be better to write different routes into the navigation and handle it in 3 different components?
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)
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',
},
});
I have a component Logitem.js which has a DatePickerIOS component.
The component works as expected but for some reason the datepicker component's layout is messed up as shown below.
Ideally the datepicker component should be on top followed by the two buttons (with adequate space between datepicker component and the buttons)
Logitem.js code
import React, { Component } from 'react';
import { Text, View, Modal, DatePickerIOS, TextInput, TouchableHighlight } from 'react-native';
export default class Logitem extends Component {
state = {
//selecteddate: '1',
selectedweight: this.props.weight,
showmodal: false,
selecteddate: new Date(86400000 * this.props.logdate),
}
componentDidMount() {
console.log('State ==> '+this.state.selecteddate+' Logstring date ==> '+this.props.logstringdate);
}
deleteSelectedRecord(){
this.setState({ showmodal: false });
this.props.invokedelete(this.state.selecteddate);
}
saveSelectedRecord(){
this.setState({ showmodal: false });
this.props.invokesave(this.state.selecteddate, this.state.selectedweight);
}
onWeightClick = () => {
this.setState({ showmodal: true }, () => {
});
}
onDateChange(date) {
this.setState({
selecteddate: date
});
}
render() {
return (
<View style={styles.containerStyle}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.showmodal}
onRequestClose={() => { alert("Modal has been closed.") }}
>
<View style={{ marginTop: 22 }}>
<DatePickerIOS
date={this.state.selecteddate}
mode="date"
onDateChange={(date) => this.onDateChange(date)}
style={{ height: 100, width: 300 }}
/>
</View>
<View style={{ marginTop: 22, borderColor: '#ddd', borderWidth: 5 }}>
<TextInput
returnKeyType="done"
keyboardType='numeric'
style={{
height: 40,
width: 60,
borderColor: 'gray',
borderWidth: 1,
}}
onChangeText={(text) => this.setState({ selectedweight: text })}
value={this.state.selectedweight.toString()}
/>
<Text>KG</Text>
<TouchableHighlight style={styles.buttonstyle} onPress={this.deleteSelectedRecord.bind(this)}>
<Text style={styles.buttontextstyle}>Delete</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonstyle} onPress={this.saveSelectedRecord.bind(this)}>
<Text style={styles.buttontextstyle}>Save</Text>
</TouchableHighlight>
</View>
</Modal>
<View style={styles.headerContentStyle}>
<Text>{this.props.logstringdate}</Text>
<Text>{this.props.bmi}</Text>
</View>
<View style={styles.thumbnailContainerStyle}>
<Text onPress={this.onWeightClick}>{this.props.weight}</Text>
</View>
</View>
);
}
};
const styles = {
containerStyle: {
borderWidth: 1,
borderRadius: 2,
borderColor: '#ddd',
borderBottomWidth: 1,
//shadowColor: '#000',
//shadowOffset: { width: 0, height: 2},
//shadowOpacity: 0.1,
//shadowRadius: 2,
//elevation: 1,
marginLeft: 5,
marginRight: 5,
marginTop:10,
},
thumbnailContainerStyle: {
justifyContent: 'center',
alignItems: 'center',
marginLeft: 10,
marginRight: 10,
flexDirection: 'row'
},
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
buttonstyle: {
marginRight: 40,
marginLeft: 40,
marginTop: 10,
paddingTop: 20,
paddingBottom: 20,
backgroundColor: '#68a0cf',
borderRadius: 10,
borderWidth: 1,
borderColor: '#fff'
},
buttontextstyle: {
color: '#fff',
textAlign: 'center',
}
};