I'm practicing my React Native programming and I have an issue with the Flex Layout that I don't seem to understand pretty well
I wanted to make my test app look like this image below
Sample App
But in the end, this is what I get. There is some misalignment in the 'Home' text which suppose to be centered properly and a missing gap on the two right icons.
Sample Test App
I have tried putting padding on the two icon but have no luck with in.
Here's my code:
import React from 'react';
import Icon from 'react-native-vector-icons/Feather';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<View style={styles.headerBrandingContainer}>
<Text style={styles.headerBranding}>Brand</Text>
</View>
<View style={styles.headerRowContainer}>
<Icon name="menu" size={30} color="white" />
<Text style={styles.headerRowPage}>Home</Text>
<View style={styles.headerRowIcons}>
<Icon name="filter" size={30} color="white" />
<Icon name="search" size={30} color="white" />
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
headerContainer: {
backgroundColor: '#3498db',
height: 180,
justifyContent: 'center',
},
headerBrandingContainer: {
marginTop: 50,
alignItems: 'center',
},
headerBranding: {
fontSize: 40,
fontWeight: '400',
letterSpacing: 1,
color: '#fff',
},
headerRowContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
margin: 10
},
headerRowIcons: {
//backgroundColor: 'red',
flexDirection: 'row',
justifyContent: 'space-between',
},
headerRowPage: {
// marginLeft:20,
fontSize: 25,
fontWeight: '500',
color: '#fff',
}
});
To align childs of headerContainer vertically you should use alignItems with the code below :
headerContainer: {
display: 'flex',
backgroundColor: '#3498db',
height: 180,
justifyContent: 'center',
alignItems: 'center'
}
A usefull resource to understand flexbox : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Remove too your marginTop on headerBrandingContainer styles.
EDIT:
Finally I think the best way is to make some modifications in the component tree so that the headerRowContainer items are all flex elements to 1. In this way, the title is always centered (the views having the same size) and we can now manage the placement of buttons without impacting the rest. It works perfectly for me.
import React from 'react';
import Icon from 'react-native-vector-icons/Feather';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<View style={styles.headerBrandingContainer}>
<Text style={styles.headerBranding}>Brand</Text>
</View>
<View style={styles.headerRowContainer}>
<View style={styles.buttonsContainerLeft}>
<Icon name="menu" size={30} color="white" />
</View>
<View style={styles.titleContainer}>
<Text style={styles.headerRowPage}>Home</Text>
</View>
<View style={styles.headerRowIcons}>
<Icon
name="filter"
size={30}
color="white"
style={styles.filterIcon}
/>
<Icon name="search" size={30} color="white" />
</View>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column'
},
headerContainer: {
backgroundColor: '#3498db',
height: 180,
justifyContent: 'center'
},
headerBrandingContainer: {
marginTop: 50,
alignItems: 'center'
},
headerBranding: {
fontSize: 40,
fontWeight: '400',
letterSpacing: 1,
color: '#fff'
},
headerRowContainer: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
margin: 10
},
buttonsContainerLeft: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start'
},
titleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
headerRowIcons: {
flex: 1,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'flex-end'
},
headerRowPage: {
fontSize: 25,
fontWeight: '500',
color: '#fff'
},
filterIcon: {
marginRight: 20
}
});
Related
(React native )
Here is my code for one screen(DetailsScreen) and I want to make other screen(IngredientScreen) with same output how to do that. when I tried to copy the same code in IngredientScreen I am getting some error. what kinds of modification do I need in DetailsScreen and what kinds of code need to be added in IngredientScreen. page need to be navigate from DetailsScreen to IngredientScreen. (react native )
Codes are here :-
import React from "react";
import { SafeAreaView, StyleSheet, View, Text, Image } from "react-native";
import { ScrollView, TouchableOpacity } from "react-native-gesture-handler";
import Icon from "react-native-vector-icons/MaterialIcons";
import COLORS from "../../consts/colors";
import foods from "../../consts/foods";
import { SecondaryButton } from "../components/Button";
const DetailsScreen = ({ navigation, route }) => {
const item = route.params;
return (
<SafeAreaView style={{ backgroundColor: COLORS.white }}>
<View style={style.header}>
<Icon name="arrow-back-ios" size={28} onPress={navigation.goBack} />
<Text style={{ fontSize: 20, fontWeight: "bold" }}>Details</Text>
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<View
style={{
justifyContent: "center",
alignItems: "center",
height: 280,
}}
>
<Image source={item.image} style={{ height: 220, width: 220 }} />
</View>
<View style={style.details}>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text
style={{ fontSize: 25, fontWeight: "bold", color: COLORS.white }}
>
{item.name}
</Text>
</View>
<Text style={style.detailsText}>{item.details}</Text>
<View style={{ marginTop: 40, marginBottom: 40, color: "red" }}>
<TouchableOpacity
onPress={() => navigation.navigate("IngredientScreen")}
>
<SecondaryButton title="Ingredients..." />
</TouchableOpacity>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
};
const style = StyleSheet.create({
header: {
paddingVertical: 20,
flexDirection: "row",
alignItems: "center",
marginHorizontal: 20,
},
details: {
paddingHorizontal: 20,
paddingTop: 40,
paddingBottom: 60,
backgroundColor: COLORS.primary,
borderTopRightRadius: 40,
borderTopLeftRadius: 40,
},
iconContainer: {
backgroundColor: COLORS.white,
height: 50,
width: 50,
justifyContent: "center",
alignItems: "center",
borderRadius: 30,
},
detailsText: {
marginTop: 10,
lineHeight: 22,
fontSize: 16,
color: COLORS.white,
},
});
export default DetailsScreen;
You could create a new component and then import it in both screens. For example:
const DetailScreen = () => {
return <ReusableComponent />
}
const Ingredientcreen = () => {
return <ReusableComponent />
}
export const ReusableComponent = () => {
return (
<SafeAreaView style={{ backgroundColor: COLORS.white }}>
<View style={style.header}>
<Icon name="arrow-back-ios" size={28} onPress={navigation.goBack} />
<Text style={{ fontSize: 20, fontWeight: "bold" }}>Details</Text>
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<View
style={{
justifyContent: "center",
alignItems: "center",
height: 280,
}}
>
<Image source={item.image} style={{ height: 220, width: 220 }} />
</View>
<View style={style.details}>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text
style={{ fontSize: 25, fontWeight: "bold", color: COLORS.white }}
>
{item.name}
</Text>
</View>
<Text style={style.detailsText}>{item.details}</Text>
<View style={{ marginTop: 40, marginBottom: 40, color: "red" }}>
<TouchableOpacity
onPress={() => navigation.navigate("IngredientScreen")}
>
<SecondaryButton title="Ingredients..." />
</TouchableOpacity>
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}
I have a modal that contains various children components. One of them being a calendar component that is opened after pressing the text "Select Date"
Upon opening the Calendar component renders underneath the other components on the page.
I have tried using position: 'absolute' with a higher zIndex but I still cannot get the Calendar Component to render on top of everything else...how can I accomplish this?
JSX For the components
<View style={styles.container}>
<View style={styles.routineitems}>
<TouchableOpacity >
<Text style={{ }}>Due Date</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>calendarShouldShow(calendarVisible)}>
<Text style={{ }}>Select Date</Text>
</TouchableOpacity>
</View>
<Calendar style={{position: 'absolute',zIndex: 4}}/>
<View style={styles.routineitems}>
<Text>Tags</Text>
<DropDownPicker
placeholder="Tags"
/>
</View>
<View style={styles.routineitems}>
<Text>Notes</Text>
<TextInput
style={styles.input}
onChangeText ={ value => setNotes(value)}
value={notes}
laceholder="Notes"
textAlign={'right'}
/>
</View>
</View>
STYLESHEET
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
width: '100%'
},
routineitems: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
width: '90%',
marginBottom: '1%',
marginTop: '1%',
alignItems: 'center',
zIndex: 0
},
input: {
height: 40,
width: '30%',
borderRadius: 20,
backgroundColor: 'white',
fontSize: 50,
textAlignVertical:'bottom',
paddingTop: 0,
paddingBottom:0,
textAlign: 'right'
}
});
I'm having incredible difficulty figuring out why my stylesheet isn't working the way that I want it to -- I want both the icon [note the comments] as well as the button on the bottom to appear centered, but both currently appear left-aligned. Would be grateful for any + all direction.
Here are my imports:
import { useNavigation } from '#react-navigation/native';
import React from 'react';
import {
Text,
SafeAreaView,
ScrollView,
View,
TouchableOpacity,
ActivityIndicator,
Alert
} from 'react-native';
import { withNavigation } from 'react-navigation';
import { firebase } from '../../../../firebase/config';
import styles from './styles';
import DateTimePicker from '#react-native-community/datetimepicker';
import { Sae } from 'react-native-textinput-effects';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
import { FontAwesome } from '#expo/vector-icons'
Here is the code returned from my class component:
<SafeAreaView style={styles.container}>
<ScrollView>
<View style={styles.inputContainer}>
<View>
<Text style={styles.title}>Create An Event</Text>
</View>
<Sae
style={{marginLeft: 10, marginRight: 10, marginBottom: 10}}
labelStyle={{color: '#656565'}}
label={'Event Name'}
iconClass={FontAwesomeIcon}
iconName={'calendar-check-o'}
iconColor={'#e95530'}
inputPadding={16}
labelHeight={20}
borderHeight={2}
autoCapitalize={'none'}
autoCorrect={false}
/>
<Sae
style={{marginLeft: 10, marginRight: 10}}
labelStyle={{color: '#656565'}}
inputStyle={{fontSize: 16}}
label={'Event Description'}
iconClass={FontAwesomeIcon}
iconName={'pencil'}
iconColor={'#e95530'}
inputPadding={16}
labelHeight={20}
borderHeight={2}
autoCapitalize={'none'}
autoCorrect={false}
/>
<View style={styles.break1}></View>
<View style={styles.break2}><FontAwesome name='circle' color='#e6a80c'/></View> //would like this icon to be centered
<View style={styles.break3}></View>
<View style={styles.indInputContainer}>
<Text style={styles.text}>Date </Text>
<DateTimePicker
testID='datePicker'
value={this.state.date}
mode='date'
is24Hour={true}
display='default'
onChange={this.onChange}
placeholder='Select a date'
style={{ marginHorizontal: 10 }}
/>
</View>
<View style={styles.indInputContainer}>
<Text style={styles.text}>Start Time </Text>
<DateTimePicker
testID='timePicker'
value={this.state.eventStartTime}
mode='time'
is24Hour={true}
display='default'
onChange={this.onChange}
placeholder='Start time'
style={{ marginHorizontal: 10 }}
/>
</View>
<View style={styles.indInputContainer}>
<Text style={styles.text}>End Time </Text>
<DateTimePicker
testID='timePicker'
value={this.state.eventEndTime}
mode='time'
is24Hour={true}
display='default'
onChange={this.onChangeEventEndTime}
placeholder='End time'
style={{ marginHorizontal: 10 }}
/>
</View>
<View style={styles.indInputContainer}>
<Text style={styles.text}>Guests' Votes Due By </Text>
<DateTimePicker
testID='datePicker'
value={this.state.votingDeadline}
mode='date'
is24Hour={true}
display='default'
onChange={this.onChangeVotingDeadline}
placeholder='Votes Due By'
style={{ marginHorizontal: 10 }}
/>
</View>
</View>
<View style={styles.buttonContainer}> //would like this button to appear centered also
<TouchableOpacity
style={styles.button}
onPress={() => this.storeEvent()}
>
<Text style={styles.Btn}>Create Event</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
And here is the stylesheet:
export default StyleSheet.create({
container: {
backgroundColor: '#ffffff',
flex: 1,
justifyContent: 'center'
},
inputContainer: {
padding: 10
},
indInputContainer: {
margin: 8
},
break1: {
marginBottom: 20,
marginTop: 20
},
break2: {
alignContent: 'center',
justifyContent: 'center'
},
break3: {
marginTop: 10,
marginBottom: 10
},
text: {
fontSize: 16,
color: '#656565',
},
preferences: {
fontWeight: 'bold',
fontSize: 20,
margin: 5,
},
title: {
padding: 5,
fontSize: 16,
fontWeight: 'bold',
color: '#e95530'
},
buttonContainer: {
justifyContent: 'center',
alignContent: 'center'
},
button: {
backgroundColor: '#e95531',
margin: 10,
marginTop: 20,
height: 48,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
width: 275,
},
Btn: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
preloader: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
},
});
Would be super grateful for some help. Thank you!
I wanted to implement my own font (from google) to use it inside my app. I loaded it and it works because some text gets changed by it. However some text doenst change which doesnt make sense to me.
I guess its a bug somehow maybe somebody has experienced this. Its a simple screen with simple code.
import React, {Component} from 'react';
import {View, Text, StyleSheet, Button} from 'react-native';
import COLORS from '../assets/COLORS';
import {TextInput} from 'react-native-gesture-handler';
class BMI extends Component {
render() {
const BMI = 20;
return (
<View style={styles.container}>
<Text style={styles.textStyle}> BMI - Calculator </Text>
<Text style={{color: COLORS.white, fontSize: 20}} >Dein momentaner BMI: <Text style={{color: COLORS.primary, fontSize: 24}} >{BMI}</Text> </Text>
<View>
<View style={styles.InputContainer}>
<Text style={styles.inputText}>AGE</Text>
<TextInput style={styles.TextInput} />
</View>
<View style={styles.InputContainer}>
<Text style={styles.inputText}>HEIGHT</Text>
<TextInput style={styles.TextInput} />
</View>
<View style={styles.InputContainer}>
<Text style={styles.inputText}>WEIGHT</Text>
<TextInput style={styles.TextInput} />
</View>
<View style={{marginTop: 25, marginHorizontal: 15}}>
<Button onPress={() => alert("Hello")} title="Calculate" color={COLORS.lightB} />
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
// justifyContent: "center",
backgroundColor: COLORS.darkBG,
},
textStyle: {
color: COLORS.lightB,
fontSize: 30,
fontWeight: 'bold',
marginVertical: 30,
fontFamily: "Pacifico"
},
InputContainer: {
justifyContent: 'space-around',
flexDirection: 'row',
width: '100%',
marginVertical: 20,
},
inputText: {
color: COLORS.white,
width: '30%',
marginLeft: 15,
fontSize: 18,
fontFamily: "Pacifico"
},
TextInput: {
backgroundColor: COLORS.primary,
width: '60%',
color: COLORS.white,
fontFamily: "Pacifico"
},
});
export default BMI;
As u can see I load pacifico and it works but only for this text ( see pic below ):
I'm currently working on my React Native's app UI and an alignment problem is killing me: I can't get my text box and text input's texts aligned horizontally.
Here is an excerpt of the render for a line:
render() {
return (
<View style={styles.container}>
<View style={styles.line}>
<Text style={styles.textLabel}>Player name:</Text>
<TextInput
style={styles.textBox}
onChangeText={(playerNameState) => this.setState({playerNameState })}
value={this.state.playerNameState} />
</View>
</View>
);
}
And here are the styles I use (background colour is just for boundingbox reference:
const styles = StyleSheet.create({
container: {
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'center',
flex: 1,
backgroundColor: 'white'
},
line: {
flexDirection: 'row',
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
margin: 5,
height: 50
},
textLabel: {
height: 50,
fontSize: 18,
backgroundColor: 'blue',
alignItems: 'center'
},
textBox: {
color: 'grey',
height: 50,
fontSize: 18,
backgroundColor: 'red',
flexGrow: 1,
alignItems: 'center'
}
I think I shouldn't be needing as many alaignItems, but I just wanted to show you what I tried. Any ideas?
Wrap those Text(Input)-Components into Views and it should work:
render() {
return (
<View style={styles.container}>
<View style={styles.line}>
<View style={styles.textLabel}>
<Text>Player name:</Text>
</View>
<View style={styles.textBox}>
<TextInput
onChangeText={(playerNameState) => this.setState({playerNameState })}
value={this.state.playerNameState} />
</View>
</View>
</View>
);}
You can also add justifyContent: 'center' to styles.textBox & textLabel to align the content vertically.