When React Native Text component's height is higher than text(inside Text), text will be topping (vertical align top) and cannot be set vertical align center.
It is like this picture. (Inspect Text component)
<View style={{ display: 'flex', justifyContent: 'center', alignItem: 'center', height: 96 }}>
<Text style={{ fontSize: 32 }}>Select</Text>
</View>
display: 'flex' worked in View component but it doesn't work Text component.
So, I don't know how to set vertical align center.
Only one way I know is set height size in Text component but it is not a good way...
I want to know correct way to set vertical align for Text component.
<View style={{ flex: 1, alignItem: 'center' }}>
<Text style={{ fontSize: 32 }}>Select</Text>
</View>
Add justifyContent: 'center' in your View style. Modify your code like this :
<View style={{ height: 96, justifyContent: 'center' }}>
<Text style={{ fontSize: 32 }}>Select</Text>
</View>
Related
I am trying to make the corners of the bottom sheet provided by the react-native-bottom-sheet rounded by passing the style prop to it. But the rounded corners are being overlapped by something which I don't know. How do I make the the corners rounded?
Screenshot:
Code:
<BottomSheet
style={{
flex: 1,
borderWidth: 5,
borderColor: "red",
backgroundColor: "blue",
borderRadius: 50
}}
index={1}
ref={bottomSheetRef}
snapPoints={snapPoints}
onChange={handleSheetChange}
>
<View
style={{
backgroundColor: "lightgreen",
marginTop: 30,
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<View style={{ backgroundColor: "white" }}>
<Text>
I am back
</Text>
</View>
</View>
</BottomSheet>
This BottomSheet component is wrapped inside a View with flex: 1
Just added overflow: hidden to the BottomSheet's style prop and it worked.
I ran into the same problem but found another solution because I was using a Handler that was outside the BottomSheet so adding overflow: 'hidden' just hid my Handler.
Reading the code I realized that the style prop that is passed to BottomSheet is added to the code as containerStyle here, but the component in charge of defining the rounded corners is actually the BackgroundComponent which has the border radius in its styles.
So, in order to get a BottomSheet with a custom corner radius is better to add a separate backgroundComponent with all the modifications we want.
Like this:
function customBackground({ pointerEvents, style }) {
return (
<View
pointerEvents={pointerEvents}
style={[styles.bgContainer, style]}
/>
);
}
function renderSheet(){
return(
<BottomSheet
index={1}
ref={bottomSheetRef}
snapPoints={snapPoints}
onChange={handleSheetChange}
backgroundComponent={customBackground}
>
<View
style={{
backgroundColor: "lightgreen",
marginTop: 30,
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}}
>
<View style={{ backgroundColor: "white" }}>
<Text>
I am back
</Text>
</View>
</View>
</BottomSheet>
;)
}
const styles = StyleSheet.create({
bgContainer: {
borderTopLeftRadius: 40,
borderTopRightRadius: 40,
backgroundColor: "blue"
},
})
I want to achieve the following:
I want to display a label next to a centered value.
As far as I can see that's not possible with flexbox, right?
How could I achieve that?
Additionally I'd like to have the base-aligned, but currently this option is not working on Android. Therefore I'm using hardcoded paddings for the smaller text boxes. Any other Idea for that?
Another suggestion, if you don't want to use empty Views, is to position Value to the center, and then have the unit positioned absolute (so it goes off the flex) and to the bottom so you ensure it's base-aligned to Value.
<View style={styles.container}>
<Text style={styles.value}>
Value
<Text style={styles.unit}>unit</Text>
</Text>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'lightgrey',
},
value: {
backgroundColor: '#eee',
textAlign: 'center',
fontSize: 20,
position: 'relative',
},
unit: {
fontSize: 12,
position: 'absolute',
bottom: 0,
},
});
You can use use 3 flex boxes placed horizontally to get a similar effect. Leave the left box blank.
(Ive added background colors for reference)
<View style={styles.container}>
<View
style={{
flexDirection: 'row',
}}>
<View style={{ flex: 1}} /> {/* blank view */}
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
}}>
<Text style={{ fontSize: 30 }}>Value</Text>
</View>
<View
style={{
flex: 1,
justifyContent: 'flex-end',
alignItems: 'fllex-start',
}}>
<Text style={{ fontSize: 12 }}>Unit</Text>
</View>
</View>
</View>
For the life of me, I can't center the headerTitle component. Ideas?
class GroupSelectionScreen extends React.Component{
static navigationOptions = ({navigation}) => {
return {
headerLeft: <View>
<Image source={logoImg} style={{width:72, height:33, marginLeft:5}}/>
</View>,
headerStyle: {
backgroundColor: theme.colors.darkBlue,
height: 75,
},
headerTitle: <View style={{
alignItems: "center",
flexDirection: 'row',
}}>
<View style={{backgroundColor: statusColor, width: 15, height: 15, borderRadius: 8}}></View>
<Text style={{color: 'white', fontSize: 25}}>{username}</Text>
</View>,
headerRight: <SetStatusButton onPress={navigation.getParam('toggleSetStatus')}/>,
};
};
Because you are using flexDirection:'row' you will probably want to add the property justifyContent:'center' to center the content of the view horizontally
This is due to the fact that justifyContent works on the primary axis and alignItems work on the secondary axis. Setting the flexDirection as row changes the primary axis to be row.
Adding flexDirection to a component's style determines the primary axis of its layout.
Adding justifyContent to a component's style determines the distribution of children along the primary axis.
You can see more in the docs
https://facebook.github.io/react-native/docs/flexbox
Here is a snack https://snack.expo.io/#andypandy/flexdirection
Each of the three views have flexDirection: 'row'
The first view has justifyContent: 'center' and the text is centred horizontally.
The second view has alignItems: 'center' and the text is centred vertically.
The third view has both justifyContent: 'center' and alignItems: 'center' and the text is centred horizontally and vertically
Here is an image of what it looks like
And here is the code
<View>
<View style={{flexDirection: 'row', justifyContent: 'center', backgroundColor: 'yellow', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
<View style={{flexDirection: 'row', alignItems: 'center', backgroundColor: 'cyan', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems:'center', backgroundColor: 'forestgreen', height: 100, width: 100, margin: 10}} >
<Text>Hello</Text>
</View>
</View>
Update
In react-navigation there appears to be a difference between how headerTitle given by the question poster is handled in Android and iOS.
In iOS the headerTitle centres vertically and horizontally, however in Android it centres only vertically and is aligned left. Obviously this is not ideal.
There is a way to make it work in both iOS and Android, simply
Wrap the original header in a View with flex:1
Make sure the original header's View has a style with justifyContent: 'center' and alignItems: 'center'
Here is the code for the new headerTitle
<View style={{flex: 1}}>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<View style={{backgroundColor: 'green', width: 15, height: 15, borderRadius: 8}}/>
<Text>Spencer</Text>
</View>
</View>
Here is a snack showing it working https://snack.expo.io/#andypandy/navigation-header
Here is an example of what am trying to achieve and below is a breakdown of the component structure
and this is how currently the code is:
<View style={styles.buttonHolder}>
<Text style={styles.greenButtonIcon}>
FB
</Text>
<Text style={styles.greenButtonText}>
{this.props.buttonName}
</Text>
</View>
My problem here since the text is center aligned to the full box i cannot have a flex value for the text and the icon since that will make them have their own space and wont float.
Can you please help. Do let me know if you need more information.
Try putting them in an absolute view within the buttonHolder. Set buttonHolder to justifyContent and alignItems center. Then make the green button alignSelf to flex-start:
<View style={styles.buttonHolder}>
<View style={styles.absolute}>
<Text style={styles.greenButtonIcon}>
FB
</Text>
</View>
<View style={styles.absolute}>
<Text style={styles.greenButtonText}>
{this.props.buttonName}
</Text>
</View>
</View>
const styles = StyleSheet.create({
absolute: {
position: 'absolute',
height: '100%',
width: '100%',
alignContent: 'center',
justifyContent: 'center'
},
styles.greenButtonIcon: {
alignSelf: 'flex-start'
}
})
React native supports use of zIndex as similar to CSS assign the item you want to be floating a higher zIndex and the other item a lower zIndex.
I have an element that I want to float right, for example
<View style={{width: 300}}>
<Text style={{backgroundColor: "#DDD"}}>Hello</Text>
</View>
How can the Text be floated / aligned to the right? Also, why does the Text take up the full space of the View, instead of just the space for "Hello"?
why does the Text take up the full space of the View, instead of just the space for "Hello"?
Because the View is a flex container and by default has flexDirection: 'column' and alignItems: 'stretch', which means that its children should be stretched out to fill its width.
(Note, per the docs, that all components in React Native are display: 'flex' by default and that display: 'inline' does not exist at all. In this way, the default behaviour of a Text within a View in React Native differs from the default behaviour of span within a div on the web; in the latter case, the span would not fill the width of the div because a span is an inline element by default. There is no such concept in React Native.)
How can the Text be floated / aligned to the right?
The float property doesn't exist in React Native, but there are loads of options available to you (with slightly different behaviours) that will let you right-align your text. Here are the ones I can think of:
1. Use textAlign: 'right' on the Text element
<View>
<Text style={{textAlign: 'right'}}>Hello, World!</Text>
</View>
(This approach doesn't change the fact that the Text fills the entire width of the View; it just right-aligns the text within the Text.)
2. Use alignSelf: 'flex-end' on the Text
<View>
<Text style={{alignSelf: 'flex-end'}}>Hello, World!</Text>
</View>
This shrinks the Text element to the size required to hold its content and puts it at the end of the cross direction (the horizontal direction, by default) of the View.
3. Use alignItems: 'flex-end' on the View
<View style={{alignItems: 'flex-end'}}>
<Text>Hello, World!</Text>
</View>
This is equivalent to setting alignSelf: 'flex-end' on all the View's children.
4. Use flexDirection: 'row' and justifyContent: 'flex-end' on the View
<View style={{flexDirection: 'row', justifyContent: 'flex-end'}}>
<Text>Hello, World!</Text>
</View>
flexDirection: 'row' sets the main direction of layout to be horizontal instead of vertical; justifyContent is just like alignItems, but controls alignment in the main direction instead of the cross direction.
5. Use flexDirection: 'row' on the View and marginLeft: 'auto' on the Text
<View style={{flexDirection: 'row'}}>
<Text style={{marginLeft: 'auto'}}>Hello, World!</Text>
</View>
This approach is demonstrated, in the context of the web and real CSS, at https://stackoverflow.com/a/34063808/1709587.
6. Use position: 'absolute' and right: 0 on the Text:
<View>
<Text style={{position: 'absolute', right: 0}}>Hello, World!</Text>
</View>
Like in real CSS, this takes the Text "out of flow", meaning that its siblings will be able to overlap it and its vertical position will be at the top of the View by default (although you can explicitly set a distance from the top of the View using the top style property).
Naturally, which of these various approaches you want to use - and whether the choice between them even matters at all - will depend upon your precise circumstances.
You can directly specify the item's alignment, for example:
textright: {
alignSelf: 'flex-end',
},
For me setting alignItems to a parent did the trick, like:
var styles = StyleSheet.create({
container: {
alignItems: 'flex-end'
}
});
You are not supposed to use floats in React Native. React Native leverages the flexbox to handle all that stuff.
In your case, you will probably want the container to have an attribute
justifyContent: 'flex-end'
And about the text taking the whole space, again, you need to take a look at your container.
Here is a link to really great guide on flexbox: A Complete Guide to Flexbox
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-end' }}>
<Text>
Some Text
</Text>
</View>
flexDirection: If you want to move horizontally (row) or vertically (column)
justifyContent: the direction you want to move.
Use flex: 1 and alignItems: 'flex-end' in View styling. Make sure to include flex: 1. That is the key to make the element float right
using flex
<View style={{ flexDirection: 'row',}}>
<Text style={{fontSize: 12, lineHeight: 30, color:'#9394B3' }}>left</Text>
<Text style={{ flex:1, fontSize: 16, lineHeight: 30, color:'#1D2359', textAlign:'right' }}>right</Text>
</View>
You can float:right in react native using flex:
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
for more detail: https://facebook.github.io/react-native/docs/flexbox.html#flex-direction
const styles = StyleSheet.create({
flowRight: {
flex:1,
justifyContent: 'end',
alignContent: 'end',
},
});
Then call styles.flowRight in your style
You can just style the text with alignSelf: 'flex-end':
<View style={{width: 300}}>
<Text style={{backgroundColor: "#DDD", alignSelf: 'flex-end'}}>Hello</Text>
</View>