React native nested flex - react-native

I am using react-native-elements. I am having difficulty in layout system of react-native.
<View style={styles.container}>
{canAccessCamera ? (
<Card style={styles.userInfo}>
<Avatar medium source={Logo} rounded />
<Text>Username</Text>
</Card>
) : (
<Text>Give me access to camera</Text>
)}
</View>
Style:
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'stretch',
justifyContent: 'flex-start',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
userInfo: {
display: 'flex',
flex: 1,
flexDirection: 'column',
alignItems: 'stretch',
justifyContent: 'flex-start',
},
});
I want items inside Card located by column not by row.
This is my result:
I want that Username stay in the right of the Avatar.

Change just this style
userInfo: {
display: "flex",
alignItems: "center",
flexDirection: "row",
justifyContent: "flex-start"
},
container:{
flex: 1,
alignItems: "stretch",
justifyContent: "flex-start",
paddingTop: 5,
backgroundColor: "#ecf0f1",
alignItems: "center"

Related

Creating Simple Grid Layout in React Native

I'm trying to create the following layout in my React Native app but haven't been able to get it right. The phone number, address and schedules are currently sitting in the middle of the screen and the "Interactive section" is at the bottom of the screen.
What am I doing wrong here? I'd appreciate some help with this layout. Thank you!
BTW, in the following image, I put the borders to show you what I want to achieve. I actually don't want to see any borders around contact info, schedule or interactive sections. The whole thing should just float on white background.
Here's the code in my component:
<View style={styles.container}>
<View style={styles.title}>
<Text style={styles.titleText}>Global Enterprises</Text>
</View>
<View style={styles.contactInfoSection}>
<View style={styles.phoneNumberSection}>
<View>
<Text>212.555.1234</Text>
</View>
<View>
<Text>1 Global Way</Text>
<Text>New York, NY 12345</Text>
</View>
</View>
<View style={styles.scheduleSection}>
<Text>Mon - Fri 8:30 - 5:30</Text>
<Text>Sat - Sun Closed</Text>
</View>
</View>
<View>
<Text style={styles.interactSection}>Other stuff</Text>
</View>
</View>
Here's my stylesheet for this particular screen:
const styles = StyleSheet.create(
{
contactInfoSection: {
alignContent: 'flex-start',
alignItems: 'flex-start',
alignSelf: 'flex-start',
flex: 2,
flexDirection: 'row',
marginTop: 20
},
container: {
alignContent: 'flex-start',
flex: 1,
flexGrow: 1,
padding: 20
},
interactSection: {
flex: 3
},
locationSection: {
alignItems: 'center',
flex: 1
},
phoneNumberSection: {
alignContent: 'center',
alignItems: 'center',
alignSelf: 'center',
flex: 1
},
scheduleSection: {
alignContent: 'center',
alignItems: 'center',
alignSelf: 'center',
flex: 1
},
title: {
alignItems: 'center',
flex: 1,
marginTop: 5
},
titleText: {
fontSize: 17,
fontWeight: 'bold'
}
}
);
export { styles };
You need to update contactInfoSection and title style. Please amend
This
contactInfoSection: {
alignContent: 'flex-start',
alignItems: 'flex-start',
alignSelf: 'flex-start',
flex: 2,
flexDirection: 'row',
marginTop: 20,
},
title: {
alignItems: 'center',
flex: 1,
marginTop: 5,
},
to this
contactInfoSection: {
flexDirection: 'row',
marginTop: 20,
},
title: {
alignItems: 'center',
marginTop: 5,
},
Good Luck

Top align elements from the bottom view

I have two Views under my main View
<View style={styles.container}>
<View style={styles.header}>
<Image
resizeMode="contain"
source={require("../assets/logo-large.png")}
style={styles.logo}
/>
</View>
<View style={styles.content}>
<TextInput
style={styles.input}
onChangeText={(email) => setEmail(email)}
defaultValue={email}
placeholder="Your email"
autoCompleteType="email"
textContentType="emailAddress"
></TextInput>
</View>
My code for styling looks like this:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
header: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "gold",
},
content: {
flex: 2,
justifyContent: "center",
alignItems: "center",
backgroundColor: "lightblue",
},
});
What I want to achieve is to have a header with logo at the top of the screen and to have the content below, but I want to have all elements in content to be top aligned. At the moment those elements are center aligned in content.
Can someone help with this?
Since your main view defaults to flex-direction = column then your content style justifyContent: "center", will arrange elements from content at vertical middle and alignItems: "center" will make them horizontal center. You need to remove those to keep the content elements to start from the top.
Please update your styles to the following.
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
header: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "gold",
},
content: {
flex: 2,
alignItems: "center",
backgroundColor: "lightblue",
},
});
Good Luck
I have adjusted it using justifyContent on header and footer styles.
header: {
flex: 1,
justifyContent: "flex-end",
alignItems: "center",
backgroundColor: "gold",
paddingBottom: "10%",
},
content: {
flex: 2,
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "lightblue",
},

Text won't vertically centre in React Native?

For some weird reason I cant get the text in one button to vertically centre in React Native:
<View style={styles.container}>
<TouchableOpacity
style={[styles.button, styles.shareButton]}
>
<View style={styles.shareButtonInner}>
<Text style={[styles.buttonText]}>
Button which wraps
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.goButton]}
>
<Text style={[styles.buttonText, styles.goButtonText]}>
Normal
</Text>
</TouchableOpacity>
</View>
const paddingVertical = 10;
const borderRadius = 8;
const fontSize = 40;
const styles = StyleSheet.create({
container: {
flexDirection: "row",
padding: 20,
},
button: {
borderRadius,
overflow: "hidden",
},
buttonText: {
textTransform: "uppercase",
paddingVertical,
color: "white",
paddingHorizontal: 20,
borderRadius,
fontSize,
textAlign: "center",
},
goButton: {
flex: 1,
backgroundColor: "gold",
justifyContent: "center",
alignItems: "center",
textAlignVertical: "center",
textAlign: "center",
alignContent: "center",
},
goButtonText: {
flex: 1,
flexDirection: "row",
backgroundColor: "blue",
justifyContent: "center",
alignItems: "center",
textAlignVertical: "center",
textAlign: "center",
alignSelf: "center",
alignContent: "center",
},
shareButton: {
flex: 1,
marginRight: 10,
},
shareButtonInner: {
display: "flex",
flex: 1,
flexDirection: "row",
backgroundColor: "#281A47",
justifyContent: "center",
alignItems: "center",
},
});
What's even stranger, when using the web view from Expo (React Native Web under the hood). I can see the Text element is display: block. If I change it to display: flex in the Chrome dev tools then it is centered. I thought all items has display: flex by default?
you can just remove "flex:1"
goButtonText: {
// flex: 1,
flexDirection: "row",
backgroundColor: "blue",
justifyContent: "center",
alignItems: "center",
textAlignVertical: "center",
textAlign: "center",
alignSelf: "center",
alignContent: "center",
},

Elevation style prop causing issues with child components

Have all my styling done for two buttons I am using inside header title to switch back between screens. The iOS implementation works perfect but the elevation style prop for Android is causing some issues. It seems to also pass down the elevation style to the child component which in my case is a TouchableOpacity which makes the button click look a little off. Is there any way to fix this issue? See images for a better idea on click impact...
I have attempted to style the TouchableOpacity to elevation:0 to override the issue with no luck. Just to get the elevation style prop to work I had to set a borderColor: 'transparent'.
static navigationOptions = (navData) => {
return {
headerTitle: (
<View style={styles.titleContainer}>
<TouchableOpacity style={styles.mapTitleButton} onPress={() => { navData.navigation.navigate('Map')}}>
<Text style={[styles.titleFont, style={color: Colors.buttonSelected}]}>MAP</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.listTitleButton}>
<Text style={styles.titleFont}>LIST</Text>
</TouchableOpacity>
</View>
),
headerLeft: (
<View style={styles.headerButtonLeft}>
<HeaderButtons HeaderButtonComponent={CustomHeaderButton}>
<Item title="menu" iconName="ios-menu" onPress={() => {
navData.navigation.toggleDrawer()
}} />
</HeaderButtons>
</View>
),
headerRight: (
<View style={styles.placeholder}></View>
),
}
}
}
const styles = StyleSheet.create({
titleContainer: {
alignItems: 'center',
flexDirection: 'row',
height: '60%',
width: '50%',
justifyContent: 'center',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.7,
shadowRadius: 1,
shadowColor: '#000000',
elevation: 5,
borderColor: 'transparent'
},
mapTitleButton: {
backgroundColor: Colors.buttonUnSelected,
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
listTitleButton: {
backgroundColor: Colors.buttonSelected,
flex:1,
alignItems: 'center',
justifyContent: 'center'
},
titleFont: {
fontFamily: 'sailec',
alignItems: 'center',
justifyContent: 'center',
textAlign: 'center',
padding: 10,
fontSize: 13
},
container: {
alignItems: 'center',
justifyContent: 'center',
flex: 1
}
});
Android Screen Capture
Did you try with: TouchableWithoutFeedback
Rather than putting elevation in the parent container I fixed it by putting it in the styling for the actual TouchableOpacity. Good to also note that for Android I needed to set borderColor: 'transparent' to also get the elevation to render.
So styling as shown below:
titleContainer: {
alignItems: 'center',
flexDirection: 'row',
height: '60%',
width: '50%',
justifyContent: 'center',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.7,
shadowRadius: 1,
shadowColor: '#000000',
},
mapTitleButton: {
backgroundColor: Colors.buttonUnSelected,
flex: 1,
alignItems: 'center',
justifyContent: 'center',
elevation: 5,
borderColor: 'transparent'
},
listTitleButton: {
backgroundColor: Colors.buttonSelected,
flex:1,
alignItems: 'center',
justifyContent: 'center',
elevation: 5,
borderColor: 'transparent'
},

Flexbox height in React Native

I'm trying to create a simple content-sized dialog box in React Native. Highest in this hierarchy I have my overlay <View> styled so:
{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: 100,
backgroundColor: COLOR
}
Within this, I have a wrapper <View> with this style:
{
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
Then I have the dialog <View>:
{
flex: 1,
width: '86%',
maxWidth: 450,
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: 'white',
borderWidth: 5,
borderColor: 'gold'
}
It looks like the problem, though, lies in the way I'm building the dialog:
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-start'}}>
<Image source={require('../../assets/icons/warning.png')}
style={{resizeMode: 'contain', height: 50, width: 48, marginRight: 30}} />
<View style={[flex: 1, flexDirection: 'column', justifyContent: 'flex-start', alignItems: 'flex-start']}>
<Text>{this.props.dialogMessage}</Text>
<View style={{flex: 1, width: '100%', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start'}}>
<Button dismissOverlay={this.props.dismissOverlay} />
</View>
</View>
</View>
With this styling I get this result:
If I change flex to 0, I get this instead:
How can I get the dialog to size to the content?
In your Dialog <View> don't set flex at all. Have it like this
{
width: '86%',
maxWidth: 450,
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: 'white',
borderWidth: 5,
borderColor: 'gold'
}
If it does not work, could you provide more code on the content inside of your Dialog view?