React-native: Layout a view next to a centered one - react-native

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>

Related

React-native: position elements in the center and flex-end

Is it possible to have the following layout (without resorting to absolute positioning)?
|...........centreElement.......RightElement|
So as if the justifyContent was 'space-between' but without the first element. I also thought to 'justifyContent: 'centre'' and then try 'justifySelf: 'flex-end' on the RightElement but this property does not exist.
<View styles={styles.container}>
<Text>centreElement</Text>
<Text>RightElement</Text>
</View>
container: {
flexDirection: 'row',
justifyContent: 'center'
}
There is mistake in your code please update code from <View styles={styles.container}> to <View style={styles.container}>
Please try the following code:
<View style={styles.container}>
<View style={{ flex: 1 }} />
<View style={{ flex: 1 }}>
<Text>centreElement</Text>
</View>
<View style={{ flex: 1 }}>
<Text>RightElement</Text>
</View>
</View>
An ideal solution without using absolute. The CentreElement text might not comes at the center, but without absolute, you cannot align it either, since you are not giving the content to take up the 100% width which is needed to rightly align the content to center. Following steps can give you the satisfying results:
Just give out flexDirection: 'row' to the container
Give both the text CentreElement and RightElement 50% width
Align both of them to right, and done!!
Code:
export default function App() {
return (
<View style={styles.container}>
{/* Txt container*/}
<View style={styles.textContainer}>
<Text style={styles.text}>
CentreElement
</Text>
<Text style={styles.text}>
RightElement
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
textContainer: {
width: '100%',
flexDirection: 'row'
},
text: {
textAlign: 'right',
width: '50%',
fontSize: 16,
fontWeight: 'bold'
}
});
Result:

How to center react native headerTitle *component* (not string)

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

How to vertically stretch two Views that are in a column formation - React Native Flex?

I have this view, where there are two Views in a column:
<View style={styles.container}>
<View style={styles.content}>
<View style={{backgroundColor: 'orange'}}>
<Text>Test</Text>
</View>
<View style={{backgroundColor: 'yellow'}}>
<Text>Test2</Text>
</View>
</View>
</View>
This is my Styles:
container: {
flexDirection: 'row',
backgroundColor: 'white',
justifyContent:'center',
alignItems:'center',
height: 80,
margin: 8,
},
content: {
flex:1,
alignItems: 'stretch',
flexDirection: 'column',
},
Here is a ScreenShot of what it looks with the above code.
How can I get the orange and yellow View to expand vertically equally, without manually defining the height for each of them?
The Text inside should be centered, but left-aligned.
Add flex: 1 to each cell to make them expand and add justifyContent: 'center' to make the text vertically centered. Like this:
<View style={styles.container}>
<View style={styles.content}>
<View style={{ backgroundColor: 'orange', flex: 1, justifyContent: 'center' }}>
<Text>Test</Text>
</View>
<View style={{ backgroundColor: 'yellow', flex: 1, justifyContent: 'center' }}>
<Text>Test2</Text>
</View>
</View>
</View>

React Native - two items: one on the left, one in the center

I have been struggling to align two items in the following positions: the first one should be on the left side of the row and the second element needs to be in the center of the row.
The following code below does not fully center my second element:
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ paddingLeft: 10 }}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{paddingRight: 10 }}>
<Text>
CENTER
</Text>
</View>
{/* Empty view so that space-between works? */}
<View
style={{paddingRight: 10 }}>
</View>
</View>
This was the closest I could get to the result I wanted. However, it does not do the trick. Could anyone know the best way to implement this successfully?
You need to add flex: 1 to parent View and children Views (all children will have flex: 1 if you want them all to be of equal size, otherwise define width/flex for each child View individually).
Try this:
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ flex: 1, paddingLeft: 10 }}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{ flex: 1, paddingRight: 10 }}>
<Text style={{ textAlign:'center' }}>CENTER</Text>
</View>
<View
style={{ flex: 1, paddingRight: 10 }}>
</View>
</View>
Added style={{ textAlign:'center' }} to Text in center View child to give you an idea of its centered position. You can modify/remove it.
When I learned Android, I was told not to use too many 'layers' of components. In that philosophy, I decided to use 'absolute' property to the left element to achieve a simpler result. In this scheme, the 'left' item is almost stick to the left wall.
<View
style={{
height: 50,
flexDirection: 'row', // a must
alignItems: 'center', // to make items center vertically.
justifyContent: 'center' // to make the second item center horizontally.
}}
>
<MaterialIcons
style={[styles.titleIcon, { position: 'absolute', left: 0 }]} // on left, still center vertically.
name='arrow-back'
onPress={() => {
navigation.goBack();
}}
/>
<Text style={styles.titleText}>{result.name}</Text> // on center automatically
</View>
<View style={{flex:1, flexDirection: 'row', justifyContent: 'space-around'}}>
<View style={{width: 50, height: 50}}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{ width: 50, height: 50}}>
<Text>CENTER</Text>
</View>
<View style={{ width: 50, height: 50}}/>
</View>

React Native: How to align inline text?

I want to do this, where both of the texts are on 1 horizontal line and one of them is in the center and the other is on the right:
This is what I have, ignore the colors (it doesn't work at all):
styles:
rowLabelText: {
color: "#0B1219",
fontFamily: Fonts.Knockout31JuniorMiddleWeight,
fontSize: 16.0,
},
Markup:
<View style={{flexDirection: 'row', height: 30, flexWrap: 'wrap', backgroundColor: 'green'}}>
<View style={{ flex: 1, backgroundColor: 'red', justifyContent: 'center', alignSelf: 'center'}}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'blue', justifyContent: 'center', alignSelf: 'flex-end' }}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
</View>
I am having trouble. Could someone assist me?
It looks like your problem is with with alignSelf you want to use alignItems.
This is how your code will look like.
Your View:
<View style={styles.textContainer}>
<View style={styles.leftContainer}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
<View style={styles.rightContainer}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
</View>
Your styles:
textContainer:{
flexDirection: 'row',
height: 30,
backgroundColor: 'green'
},
leftContainer:{
flex: 1,
justifyContent: 'center',
alignItems:'center',
backgroundColor: 'red',
},
rightContainer:{
flex: 1,
justifyContent: 'center',
alignItems: 'flex-end',
backgroundColor: 'blue',
},
rowLabelText: {
color: "#0B1219",
fontSize: 16.0,
},
One way to center text with respect to the entire width of the screen while also having some text to the right side of the centered text is to use absolute positioning on the right text.
By using absolute positioning on the right text, it will not affect the position of the centered text.
<View style={{flexDirection: 'row'}}>
<View style={{flex:1, alignItems: 'center', backgroundColor: 'red'}}>
<Text>50%</Text>
</View>
<View style={{position:'absolute', right: 20, backgroundColor: 'blue'}}>
<Text>+$0.80</Text>
</View>
</View>