Vertical centering in React Native doesn't work - react-native

I use a ScrollView and I am not able to center an icon in one of inner Views.
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
<ScrollView>
...
<View style={styles.detailRowContainer}>
<View style={{flex: 1}}>
<Text style={styles.label} numberOfLines={1}>
{'Phone Number'}
</Text>
<Text style={styles.value} numberOfLines={1}>
{phone}
</Text>
</View>
<View style={styles.round}>
<TouchableWithoutFeedback onPress={this._onPressPhone}>
<Icon size={22} name="phone" />
</TouchableWithoutFeedback>
</View>
</View>;
...
</ScrollView>
detailRowContainer: {
flexDirection: 'row',
justifyContent: 'center',
flex: 1,
marginTop: 10,
paddingBottom: 10,
borderBottomWidth: 1,
borderBottomColor: Colors.lightGray,
},
label: {
color: Colors.glofoxDark,
marginBottom: 3,
},
value: {
color: Colors.glofoxDark,
fontWeight: '800',
borderBottomWidth: 1,
borderBottomColor: Colors.lightGray,
},
round: {
backgroundColor: Colors.lightBlue,
width: 30,
height: 30,
borderRadius: 30,
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'flex-end',
flexDirection: 'row',
padding: 4,
},

The styles need to be modified in this way.
Right now you're doing
flexDirection: row along justifyContent: center. Since your first child element is taking complete parent flex, therefore it does not show its effect
paddingBottom is given but , for centering an equivalent paddingTop must be given
padding for the round style should be replaced with margin, otherwise it affects the position of the inner elements
alignItems in round , must not be flex-end, it should be replaced with center
Here are the styles that will fix the vertical centering
detailRowContainer: {
flexDirection: 'row',
alignItems: 'center',
flex: 1,
marginTop: 10,
paddingTop: 10,
paddingBottom: 10,
borderBottomWidth: 1,
borderBottomColor: Colors.lightGray,
},
round: {
backgroundColor: Colors.lightBlue,
width: 30,
height: 30,
borderRadius: 30,
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'center',
margin: 4
},

Related

How to center text vertically in its own frame in React Native?

The text is sticking to the top. How do we center it vertically
<View style={styles.formContainer}>
<View style={styles.textInputBackground}>
<Text style={styles.textInputLabelText}>Name</Text>
<TextInput style={styles.textInput} />
</View>
<View style={styles.textInputBackground}>
<Text style={styles.textInputLabelText}>Email</Text>
<TextInput style={styles.textInput} />
</View>
</View>
const styles = StyleSheet.create({
formContainer: {
marginTop: 130,
},
textInputBackground: {
marginTop: 12,
backgroundColor: 'rgba(0, 0, 0, 0.08)',
flexDirection: 'row',
height: 46,
marginLeft: 16,
marginRight: 16,
borderRadius: 8,
},
textInputLabelText: {
backgroundColor: 'blue',
color: 'red',
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center',
textAlignVertical: 'center',
flex: 2,
},
textInput: {
flex: 12,
},
})
Hi there I've updated your style. this will center your input
textInputBackground: {
marginTop: 12,
backgroundColor: 'rgba(0, 0, 0, 0.08)',
flexDirection: 'row',
height: 46,
marginLeft: 16,
marginRight: 16,
borderRadius: 8,
alignItems:"center", // **<--- add this line**
},
To make text center change style to this
textInputLabelText: {
backgroundColor: 'blue',
color: 'red',
justifyContent: 'center',
alignSelf: 'center', //just change alignItem to alignSelf
textAlign: 'center',
textAlignVertical: 'center',
flex: 2,
},

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'
},

how set a View background color to red and it should be transparent

I have a Imagebackground for my parentconatiner, I want to set backgroundColor of one of my childView to red and it should be transparent so that the parent container image is visible
it should be like this
sample image
here is my code
import React, { Component } from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import colors from '../styles/colors';
import strings from '../localization/strings';
class Appointments extends Component {
render() {
return (
<View style={styles.Container}>
<View style={{ backgroundColor: 'rgba(52, 0, 0, 0.8)', shadowOpacity: 0.2, padding: 5 }}>
<View style={styles.childContainer}>
<Image style={{ justifyContent: 'flex-start', alignItems: 'flex-start' }} source={require('../assets/calender-Icon.png')}
/>
<View style={styles.dateTextContainer}>
<Text style={styles.childText}>Appointment</Text>
<Text style={[styles.childText, { fontSize: 26 }]}>Oct24, 2018</Text>
<Text style={[styles.childText, { fontSize: 16, fontWeight: 'bold' }]}>10:30 am</Text>
</View>
</View>
</View>
<View style={styles.borderText}>
<View style={{ flexDirection: 'row' }}>
<Image source={require('../assets/add-Icon.png')} />
<Text style={[styles.itemName, { fontSize: 16 }]}>New</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<Image source={require('../assets/seeAll-Icon.png')} />
<Text style={[styles.itemName, { fontSize: 16 }]}>See All</Text>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
Container: {
backgroundColor: colors.white,
borderRadius: 4,
borderWidth: 1,
borderColor: colors.red
},
childContainer: {
justifyContent: 'space-between',
alignItems: 'flex-start',
margin: 15,
flexDirection: 'row',
},
textStyle: {
fontSize: 16,
color: colors.black,
justifyContent: 'flex-end',
alignItems: 'flex-end',
fontWeight: 'bold'
},
childText: {
color: colors.white,
fontSize: 18,
},
dateTimeContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginHorizontal: 10,
alignItems: 'flex-end',
},
dateTextContainer: {
flexDirection: 'column',
marginHorizontal: 10,
justifyContent: 'flex-end',
alignItems: 'flex-end',
},
listItem: {
borderWidth: 1,
borderColor: colors.pureBlue,
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 5,
paddingVertical: 5,
margin: 30
},
itemName: {
fontSize: 14,
color: colors.black,
margin: 2,
paddingLeft: 4
},
border: {
borderRadius: 4,
borderWidth: 1,
borderColor: colors.light_gray,
marginHorizontal: 20
},
imageText: {
flexDirection: 'column',
margin: 10,
flexWrap: 'wrap',
flex: 1
},
borderText: {
flexDirection: 'row',
justifyContent: 'space-between',
margin: 10
}
});
export default Appointments;
I have tried rgba and opacity but still not working
please help me how to do this
You need to remove the backgroundColor of the Container to allow for transparency to go all the way through to the parent container, otherwise the transparency will only allow to see the white background behind
Container: {
// backgroundColor: colors.white,
...
},

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?

RN Android: button takes too much space when text on 2 lines

I have this button
const TestButton = ({ text }) => (
<View
style={{
width: '100%',
marginTop: 10,
padding: 10,
backgroundColor: 'red',
flexDirection: 'row',
justifyContent: 'center',
}}>
<View
style={{
backgroundColor: 'green',
padding: 10,
flexDirection: 'row',
alignItems: 'center',
}}>
<Text numberOfLines={2}>{text}</Text>
</View>
</View>
);
I want the button to be the smallest possible, and centered.
Android
On Android, as you can see it's not really the case. For the 3 case we can clearly see that the button (green) is much larger than it should be and takes all available space.
iOS
On iOS as you can see it seems to work as I expect.
Is this a bug? Are there any workaround to solve this problem on Android?
Here is an Expo snack to reproduce.
Try this
const TestButton = ({ text }) => (
<View
style={{
width: '100%',
marginTop: 10,
padding: 10,
backgroundColor: 'red',
flexDirection: 'row',
justifyContent: 'center',
}}>
<View
style={{
padding: 10,
flexDirection: 'row',
alignItems: 'center',
}}>
<Text numberOfLines={2}
style = {{
backgroundColor: 'green',
padding:10
}}>
{text}
</Text>
</View>
</View>
);
I could solve my issue with wrapping my labels into container:
itemContainer: {
flex: 1,
marginHorizontal: 25,
paddingVertical: 15,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
},
itemView: {
width: "100%"
},
newsTitle: {
fontSize: 20,
color: darkBlue,
paddingRight: 20,
fontFamily: "Helvetica-middle",
borderColor: darkBlue,
borderWidth: 1
},
newsChannel: {
paddingTop: 10,
fontSize: 16,
fontFamily: "Helvetica",
color: darkGrey
},
return (
<TouchableOpacity style={styles.itemContainer}>
<View style={styles.itemView}>
<Text style={styles.newsTitle}>{news.title}</Text>
<Text style={styles.newsChannel}>{newsChannelTitle}</Text>
</View>
<ArrowIcon />
</TouchableOpacity>
);