I am about to making an app with React Native and I have three screens with deferent styles (themes). I want to navigate among these three screens, So I am passing data from my main screen (App.js) as parent to the other three as child (screen1, screen2, screen3). I used a modal which has three button in it and i want whenever I pressed one of them, the screen change to the pressed one. This is my App.js file
import React, { useState, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import Screen1 from "./screens/CalcScreen";
import Screen2 from "./screens/Screen1";
import Screen3 from "./screens/Screen2";
export default function App() {
const [whiteScreen, setWhiteScreen] = useState(false);
const [darkScreen, setDarkScreen] = useState(false);
const [pinkScreen, setPinkScreen] = useState(false);
const whiteScreenHandler = () => {
setWhiteScreen(true);
setDarkScreen(false);
setPinkScreen(false);
};
const darkScreenHandler = () => {
setDarkScreen(true);
setWhiteScreen(false);
setPinkScreen(false);
};
const pinkScreenHander = () => {
setPinkScreen(true);
setWhiteScreen(false);
setDarkScreen(false);
};
let content = <screen1 setDarkScreen={darkScreenHandler} />;
let content2 = <Screen2 setWhiteScreen={whiteScreenHandler} />;
let content3 = <Screen3 setPinkScreen={pinkScreenHander} />;
if (darkScreen) {
content = content;
} else if (whiteScreen) {
content = content2;
} else if (pinkScreen) {
content = content3;
}
return <View style={styles.container}>{content}</View>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#374351",
},
});
And this is one of my screens and my modals in my screens, the other two screens are same in coding but not in styles and I used this modal in each three screens,(does it right to use in three screens?) anyway whenever I'm pressing modal's button to change the screens i got props.screen handler() is not a function. What is wrong in my code?
import React, { useState } from "react";
import {
StyleSheet,
Text,
ScrollView,
View,
TouchableOpacity,
Alert,
Animated,
Modal,
Pressable,
} from "react-native";
const Screen1 = (props) => {
return (
<View style={styles.screen}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.button}></View>
<Text style={styles.modalText}>Themes</Text>
<TouchableOpacity
style={styles.darkTheme}
onPress={() => {
props.setDarkScreen();
}}
>
<Text>Dark</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.whiteTheme}
onPress={() => {
props.setWhiteScreen();
}}
>
<Text>White</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.pinkTheme}
onPress={() => {
props.setPinkScreen();
}}
>
<Text>Pink</Text>
</TouchableOpacity>
<Pressable
style={[styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>X</Text>
</Pressable>
</View>
</View>
</Modal>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.openText}>{">"}</Text>
</Pressable>
</View>
)
}
const styles = StyleSheet.create({
screen: {
backgroundColor: "#fafcff",
},
centeredView: {
// flex: 1,
marginStart: 15,
justifyContent: "center",
alignItems: "center",
// marginTop: 70,
},
modalView: {
marginTop: 200,
backgroundColor: "rgba(255,255,255,0.5)",
borderRadius: 20,
padding: 20,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.5,
shadowRadius: 4,
elevation: 5,
},
button: {
borderRadius: 15,
padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
buttonOpen: {
backgroundColor: "rgba(1,143,132,0.6)",
position: "absolute",
marginTop: 45,
marginStart: -25,
elevation: 2,
height: 70,
width: 40,
},
buttonClose: {
backgroundColor: "rgba(1,1,1,1)",
height: 40,
width: 40,
borderRadius: 50,
// padding: 10,
elevation: 2,
justifyContent: "center",
alignItems: "center",
marginTop: 20,
},
textStyle: {
color: "white",
// fontWeight: "bold",
textAlign: "center",
},
modalText: {
marginBottom: 10,
textAlign: "center",
},
openText: {
fontSize: 25,
fontWeight: "bold",
color: "white",
textAlign: "right",
},
});
export default Screen1;
You can easily doing that by using "React Native Navigation". Here is the documentation:
https://reactnavigation.org/docs/getting-started. I also recommend you that you might want to create your screens into different files to make your code cleaner.
Related
I'm trying to add a navigation in this Alert with Dialog, in the 'OK' option to confirm Logout and go back to the login screen, however it's not working. Does anyone help me with this?
I'm also trying to insert a dark theme for the entire application, local expo finger printing and push notifications in setData options 2, 3, and 4, but it's a difficult task as well.. But I'm more focused on creating this Navigation in my Alert because I'm trying.
i'll be very grateful for the help :)
when I grow up, I'm going to be a great programmer.
import { SafeAreaView,Text, View, FlatList,
TouchableOpacity, StyleSheet, Image, Switch, Alert} from 'react-native';
import { Entypo } from 'react-native-vector-icons';
import React, {useState, useEffect} from 'react';
import { useNavigation } from '#react-navigation/native';
import * as LocalAuthentication from 'expo-local-authentication';
//import Auth from './Biometric'
const Settings = () =>{
const [data, setData] = useState([
{ id: 1, text: 'Perfil', image: require('../../assets/images/user.png'), chosen: false },
{ id: 2, text: 'TouchId', image: require('../../assets/images/fingerprint.png'), chosen: false },
{ id: 3, text: 'Dark/Light mode', image: require('../../assets/images/light-up.png'), chosen: false },
{ id: 4, text: 'Notificações', image: require('../../assets/images/bell-fill.png'), chosen: false },
]);
const [isRender, setisRender] = useState(false);
const navigation = useNavigation();
const handleLogout = () => {
//navigation.navigate();
Alert.alert('Logout!', 'Deseja realmente sair?', [
{
text: 'Cancelar',
onPress: () => {},
},
{
text: 'OK',
onPress:()=>
{navigation.navigate ("Login")}
},
]);
}
const renderItem = ({ item }) => {
return (
<TouchableOpacity
style={styles.item}
>
<View style={styles.avatarContainer}>
<Image source={item.image} style={styles.avatar} />
</View>
<View>
<Text style={styles.text}>{item.text}</Text>
</View>
{item.id > 1 && <Switch style={{ width: 10, alignItems: 'flex-end',
marginTop: 15, flex: 1, marginEnd: 30}}
thumbColor={item.chosen == false ? "#CDCDCD" : "#A0D800"}
trackColor={{ true: "#CDCDCD" }}
value={item.chosen}
onChange={() => setData(data.map(index => item.id === index.id
? { ...index, chosen: !index.chosen }
: index
))} />}
{item.id === 2
}
</TouchableOpacity>
);
};
return (
<SafeAreaView style={styles.container}>
<FlatList
data={data}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
extraData={isRender} />
<View style = {{alignSelf: 'center',}}>
<TouchableOpacity
onPress={()=> (handleLogout)}
style = {{borderRadius: 10,
alignItems: "center",
backgroundColor: "#A0D800",height: 50, width: 200,
bottom: 15,
shadowColor: 'rgba(0,0,0, .4)', // IOS
shadowOffset: { height: 1, width: 1 }, // IOS
shadowOpacity: 1, // IOS
shadowRadius: 1, //IOS
elevation: 2, // Android
}}>
<Text style={{color: "#ffffff",
fontWeight: 'bold', fontSize: 17,
padding: 5, bottom: 0, marginTop: 5,
}}>
SignOut
</Text>
<Entypo name={'log-out'}
style={{alignSelf: 'flex-end', bottom: 25,
marginEnd: 25}}
color={'#ffffff'}
size={20}
/>
</TouchableOpacity>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20
//marginHorizontal: 21
},
item:{
borderBottomWidth: 1,
borderBottomColor: '#808080',
alignItems: 'flex-start',
flexDirection: 'row',
},
avatarContainer: {
backgroundColor: 'transparent',
//borderRadius: 100,
height: 30,
width: 30,
justifyContent: 'center',
alignItems: 'center',
},
avatar: {
height: 25,
width: 25,
bottom: -25,
marginLeft: 30
},
text:{
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 30,
marginBottom: 10,
bottom: 5
},
});
export default Settings;
Your mistake is because of your onPress={()=> (handleLogout)}. onPress takes in a function but in your case you are making the function run another function, so your alert will not even be activated. To fix this, simply change your code to this.
onPress={handleLogout}
I am trying to implement text change and edit ends in TextInput using react-native but it's not quite working.
See the Screenshot Here
Currently, when changing the price by touch input, the price is not affected when click off.
Here are my files
CartItem.js:
import React from "react";
import {
View,
TextInput,
Image,
TouchableOpacity,
StyleSheet,
Platform,
Alert,
} from "react-native";
//Colors
import Colors from "../../../utils/Colors";
//NumberFormat
import NumberFormat from "../../../components/UI/NumberFormat";
//Icon
import { MaterialCommunityIcons } from "#expo/vector-icons";
import CustomText from "../../../components/UI/CustomText";
//PropTypes check
import PropTypes from "prop-types";
export class CartItem extends React.PureComponent {
render() {
const { item, onAdd, onDes, onRemove } = this.props;
const AddItemHandler = async () => {
await onAdd();
};
const sum = +item.item.price * +item.quantity;
const checkDesQuantity = async () => {
if (item.quantity == 1) {
Alert.alert(
"Clear cart",
"Are you sure you want to remove the product from the cart?",
[
{
text: "Cancel",
},
{
text: "Yes",
onPress: onRemove,
},
]
);
} else {
await onDes();
}
};
return (
<View style={styles.container}>
<View style={styles.left}>
<Image
style={{
width: "100%",
height: 90,
resizeMode: "stretch",
borderRadius: 5,
}}
source={{ uri: item.item.thumb }}
/>
</View>
<View style={styles.right}>
<View
style={{ flexDirection: "row", justifyContent: "space-between" }}
>
<CustomText style={styles.title}>{item.item.filename}</CustomText>
<View>
<TouchableOpacity onPress={onRemove}>
<MaterialCommunityIcons name='close' size={20} color='#000' />
</TouchableOpacity>
</View>
</View>
<CustomText style={{ color: Colors.grey, fontSize: 12 }}>
Provided by Brinique Livestock LTD
</CustomText>
<NumberFormat price={sum.toString()} />
<View style={styles.box}>
<TouchableOpacity onPress={checkDesQuantity} style={styles.boxMin}>
<MaterialCommunityIcons name='minus' size={16} />
</TouchableOpacity>
Code that I would like to be fixed starts here.
<View>
<TextInput
keyboardType='numeric'
onEndEditing={AddItemHandler}
style={styles.boxText}>{item.quantity}</TextInput>
</View>
Code that I would like to be fixed ends here.
<TouchableOpacity
onPress={AddItemHandler}
style={styles.boxMin}>
<MaterialCommunityIcons name='plus' size={16} />
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
CartItem.propTypes = {
item: PropTypes.object.isRequired,
onAdd: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onDes: PropTypes.func.isRequired,
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginHorizontal: 10,
height: 110,
borderBottomWidth: 1,
borderBottomColor: Colors.light_grey,
flexDirection: "row",
paddingVertical: 10,
alignItems: "center",
backgroundColor: "#fff",
paddingHorizontal: 10,
borderRadius: 5,
marginTop: 5,
},
left: {
width: "35%",
height: "100%",
alignItems: "center",
},
right: {
width: "65%",
paddingLeft: 15,
height: 90,
// overflow: "hidden",
},
title: {
fontSize: 14,
},
box: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
height: Platform.OS === "ios" ? 30 : 25,
backgroundColor: Colors.grey,
width: 130,
borderRadius: 5,
paddingHorizontal: 15,
marginTop: 5,
},
boxMin: {
width: "30%",
alignItems: "center",
},
boxText: {
fontSize: 16,
backgroundColor: Colors.white,
padding: 5,
},
});
Use onBlur instead of onEndEditing.
How should the input end triggered?
After a time?
When user hits enter?
When user taps anywhere to close software keyboard?
Instead of
onEndEditing={AddItemHandler}
Use:
onBlur={(e) => {AddItemHandler(e.nativeEvent.text)}}
And ensure that AddItemHandler can handle the value in e.nativeEvent.text.
I have only two buttons, and I want their backgroundColor to be changed when pressing. I don't want to use map as there are only two buttons. I have tried some ways to approach what I expect, but I am at a loss what to do.
RoundedButtonSet :
const styles = StyleSheet.create({
container: {
marginBottom: 20,
},
});
const RoundedButtonSet = ({ firstBtn, secondBtn, contentStyle }) => {
return (
<View style={[styles.container, contentStyle]}>
<RoundedButtons firstBtn={firstBtn} secondBtn={secondBtn} />
</View>
);
};
RoundedButtons :
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: colors.very_light_pink,
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: colors.very_light_pink_five,
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: colors.very_light_pink,
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: colors.iris,
},
textColor: {
color: colors.white_two,
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [isClicked, setIsClicked] = useState(true);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[styles.btn, styles.left, isClicked && styles.backgroundColor]}
onPress={() => setIsClicked(!isClicked)}
>
<Text style={[styles.btnTextStyle, isClicked && styles.textColor]}>
{firstBtn}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.right]}
onPress={() => setIsClicked()}
>
<Text style={[styles.btnTextStyle]}>{secondBtn}</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;
Should I give index directly to each button? I have got this idea, but the problem is I have no idea how to access..
You can have a simple state to keep track of which button is pressed and use that to apply styles conditionally.
Here is the working example: Expo Snack
import React, { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: 'pink',
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: 'pink',
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: 'pink',
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: 'black',
},
textColor: {
color: 'white',
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [clickedBtn, setIsClicked] = useState(null);
React.useEffect(() => {
console.log(clickedBtn);
}, [clickedBtn]);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[
styles.btn,
styles.left,
clickedBtn == 1 && styles.backgroundColor,
]}
onPress={() => setIsClicked(1)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 1 && styles.textColor]}>
firstBtn
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.btn,
styles.right,
clickedBtn == 2 && styles.backgroundColor,
]}
onPress={() => setIsClicked(2)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 2 && styles.textColor]}>
secondBtn
</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;
I want to create a design which I have attached, there are two buttons, when I click on unlimited credit the colour of the button should become red and limited should be white and when I click on limited the limited button should be red and unlimited colour should be white as shown in the image and also when I click on button it should call functions, the function will have some design part and there will be two functions one for unlimited and other for limited based on the button click it should call that function, please let me know how can I execute this.
Final Output:
Full code:
const ButtonContainer = () => {
const [btnOne, setBtnOne] = useState(false);
const [btnTwo, setBtnTwo] = useState(false);
const clickStyle = { backgroundColor: '#F5D9D0', borderColor: '#F3805E' }
return (
<View style={styles.buttonContainer}>
<TouchableOpacity
onPress={() => {
setBtnOne(true);
setBtnTwo(false);
}}
style={[
styles.button,
btnOne ? clickStyle : null,
]}>
<Text>Unlimited Credit</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {
setBtnOne(false);
setBtnTwo(true);
}}
style={[
styles.button,
btnTwo ? clickStyle : null,
]}>
<Text>Limited Credit</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-evenly',
},
button: {
borderColor: 'grey',
borderWidth: 2,
padding: 10,
borderRadius: 20,
},
});
Live working example: Expo Snack
here's a snack I created: https://snack.expo.io/#yoobit0616/two-buttons
import React, { useState } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Button } from 'react-native-elements';
import Constants from 'expo-constants';
export default function App() {
const [disabledButton, setDisabledButton] = useState(true);
return (
<View style={styles.container}>
<View style={styles.buttonView}>
<Button
style={styles.button}
onPress={() => setDisabledButton(!disabledButton)}
buttonStyle={
disabledButton
? { backgroundColor: 'white' }
: { backgroundColor: 'red' }
}
titleStyle={{ color: 'black' }}
title="Unlimited Credit"></Button>
<Button
style={styles.button}
onPress={() => setDisabledButton(!disabledButton)}
buttonStyle={
!disabledButton
? { backgroundColor: 'white' }
: { backgroundColor: 'red' }
}
titleStyle={{ color: 'black' }}
title="Limited Credit"></Button>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
buttonView: {
flexDirection: 'row',
justifyContent: 'center',
},
button: {
height: 40,
width: 150,
marginLeft: 20,
borderRadius: 5,
borderWidth: 1,
},
});
My code seems to be good but I do not understand why it is just doing nothing when I hit the "X" look at the code below please and help me out!
import React, { useState } from 'react';enter code here
import { StyleSheet, FlatList, Text, View, Image, TextInput, Button, Keyboard, TouchableOpacity, CheckBox } from 'react-native';
import Interactable from 'react-native-interactable';
export default function App() {
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
if (enteredGoal.length > 0) {
setCourseGoals(currentGoals => [...currentGoals, enteredGoal])
} else {
alert("You have to write something!")
}
}
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
courseGoals.splice(idx, 1)
setCourseGoals(courseGoals)
}
return (
<View style={styles.container}>
<View style={styles.topPart}></View>
<View style={styles.navBar}>
<Image source={require('./assets/baseline_menu_black_18dp.png/')} />
<Text style={styles.heading}> Grocery List </Text>
</View>
<View style={styles.body}>
<TextInput
style={styles.textInput}
placeholder='Groceries'
maxLength={20}
onBlur={Keyboard.dismiss}
value={enteredGoal}
onChangeText={goalInputHandler}
/>
<View style={styles.inputContainer}>
<TouchableOpacity style={styles.saveButton}>
<Button title="ADD" onPress={addGoalHandler} color="#FFFFFF" style={styles.saveButtonText} />
</TouchableOpacity>
</View>
<View style={styles.container}>
<FlatList
data={courseGoals}
renderItem={(itemData, idx) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete} onPress={() => deleteItem(idx)}>X</Text>
</View>
)}
/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topPart: {
height: '3%',
backgroundColor: '#5498A7',
},
navBar: {
height: '10%',
backgroundColor: '#5498A7',
elevation: 3,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center',
},
body: {
backgroundColor: '#edebe9',
height: '100%',
flex: 1
},
heading: {
fontWeight: "bold",
justifyContent: 'center',
paddingLeft: '13%',
fontSize: 25,
color: '#d6d4d3'
},
textInput: {
borderColor: '#CCCCCC',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 25,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#5498A7',
backgroundColor: '#5498A7',
padding: 15,
margin: 5,
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
},
groceryItem: {
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#6A686B',
padding: 15,
margin: 5,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
groceryItemText: {
color: '#d6d4d3',
},
groceryItemDelete: {
color: 'red',
fontWeight: 'bold',
fontSize: 20
}
});
I am just a beginner and am trying to figure out how to make this work better, if you have an idea please say how to fix it I would really appreciate it. This is a project I am doing just to get started with the learning process but this has been taking a bit longer than expected. Thank you!
I guess you have to change deleteItem function as following.
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
clonedGoals.splice(idx, 1)
setCourseGoals(clonedGoals)
}
You have to replace courseGoals with clonedGoals
You can use ES2015 to achieve it in fewer lines, update your delete function like this:
const deleteItem = element => {
const clonedGoals = courseGoals.filter((item) => item !== element);
setCourseGoals(clonedGoals);
}
also update your onPress instead of passing index pass the item itself like this
onPress={() => deleteItem(itemData.item)}