React Native vertical text alignment when using explicit height - css

I want to vertically center my text inside a view with an explicit height.
Center text vertically in react-native did not fully answer my question because they don't use explicit height.
When I use
<View style={styles.rightContainer}>
<Text style={styles.label2}>
Centered
</Text>
</View>
rightContainer: {
marginRight: 10,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
label2: {
height: 40,
backgroundColor: 'green',
textAlignVertical: 'center',
},
If I take away the explicit height,
label2: {
backgroundColor: 'green',
textAlignVertical: 'center',
},
it works.
I need to set the explicit height because I will convert this View to a tappable button.
How do I make this work?
What am I misunderstanding about react-native layout?

It's because the 'textAlignVertical' property is Android-only. Check the documentation on Text.
You could add an extra container wrapping the text:
export default class FlexDirectionBasics extends Component {
render() {
return (
<View style={styles.rightContainer}>
<View style={styles.labelContainer}>
<Text style={styles.label}>Centered</Text>
</View>
</View>
);
}
}
const styles = {
rightContainer: {
marginRight: 10,
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
},
labelContainer: {
height: 40,
backgroundColor: 'green',
alignItems: 'center',
justifyContent: 'center',
},
label2: {},
};

Related

How to align between two items inline left and right using flex in react native

Here's what I'm trying to achieve:
I want to align the 2 messages text label next to bargraph with background color green. The bargraph has dynamic width which renders coming from the backend and when size grows, the 2 messages label should also adjust and is always next to bargraph.
And here's what I have done sofar. It seems like that 2 messages won't show up next to bargraph with green background.
component code:
<View style={[styles.container]}>
<View style={[styles.barGraph, styles.greenDeep]}>
<View style={{ flex: 6 }}>
<Text style={styles.textLeft}>agree</Text>
</View>
<View style={{ flex: 6}}>
<Text style={styles.textRight}>3 (60 %)</Text>
</View>
</View>
<View>
<Text>2 messages</Text>
</View>
</View>
css:
container: {
flex: 1,
flexDirection: "column",
alignContent: "space-between",
},
textLeft: {
fontSize: 12,
color: 'white',
textAlign: 'left'
},
textRight: {
fontSize: 12,
color: 'white',
textAlign: 'right'
},
barGraph: {
flexDirection: 'row',
marginBottom: theme.SIZES.BASE,
width: width - theme.SIZES.BASE * 10,
padding: 10,
borderRadius: 5
},
greenDeep: {
backgroundColor: '#36d79a'
},
How would it be possible with react native's flex property?
For live editing, visit snack here live editor
To achive this:
First you have to set your flexDirection of container class to column. Set maxWidth at other container classes, and create a new class for your message with justifyContent: 'center' attribute.
container: {
flex: 1,
flexDirection: "row", /*it was column*/
alignContent: "space-between",
}
surveyDetailsContainer: {
/* some code */
maxWidth: 500,
},
container: {
/* some code */
maxWidth: 500,
},
/* some other classes*/
barGraph: {
/* some code */
maxWidth: 400,
},
/*created a new class, included the minWidth and added 3 more new attributes*/
message: {
minWidth: 5,
maxWidth: 80,
justifyContent: 'center',
marginLeft: 5,
}
And then put the new message class into:
<View style={[styles.message]}>
<Text>2 messages</Text>
</View>
Here is the whole code: https://snack.expo.dev/UwP7GVLzX
You can play around more with maxWidth, minWidth to make it responsive.

React Native prevent text from growing container width

How can I prevent the text from making its container grow in width and instead wrap to keep the width of the container? Note that I don`t want the container to have a fixed width, the width of the container is determined by its other children.
For example, the following code
class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={[styles.bubble2, {}]}>
<View
style={{ width: 100, height: 100, backgroundColor: "#ff0000" }}
/>
<Text
style={{
fontSize: 18,
flexWrap: "wrap",
backgroundColor: "#00ff00"
}}
>
Some random text goes here
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#fff",
paddingTop: 20,
alignItems: "center",
justifyContent: "center"
},
bubble2: {
backgroundColor: "orange",
paddingHorizontal: 20,
alignItems: "center",
justifyContent: "center"
}
});
renders this. Note how the text makes the container width larger to fit
and what I am trying to achieve is this without setting the width of the outer container

Flexbox: How to make children the same width as the parent?

In my React Native app, I'm having trouble with making the children the same width as the parent. Please see image below:
I want the black and the green View to take the whole screen width, therefore get rid of the white background caused by the parent.
How can I achieve this? For example, I tried to apply width: 100% to the children, doesn't work. Several solutions like this, this and this don't work here.
Here is the code:
<View style={styles.containerWholePage}>
<View>
<View style={styles.upper}></View>
<View style={styles.lower}></View>
</View>
</View>
const styles = StyleSheet.create({
containerWholePage: {
alignItems: 'center',
},
lower: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'green',
flex: 6,
width: '100%', // doesn't work
},
upper: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'black',
flex: 3,
width: '100%', // doesn't work
},
});
Do you have an idea what I'm doing wrong?
This work for me as you want.
<View style={styles.containerWholePage}>
{/* <View> */}
<View style={styles.upper}></View>
<View style={styles.lower}></View>
{/* </View> */}
</View>
const styles = StyleSheet.create({
containerWholePage: {
alignItems: 'center',
flex:1,
},
lower: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'green',
// height:100,
flex: 6,
width: '100%', // doesn't work
},
upper: {
alignItems: 'center',
alignSelf: 'stretch',
backgroundColor: 'black',
flex: 3,
//height:200,
width: '100%', // doesn't work
},
});

Grid like Flatlist component with header looking the same as rows

In react-native I am using FlatList component for rendering a grid-like list of data that looks like:
However, I want to make the first row (or header) with bold text stylesheet. Do I need to renderHeader as another FlatList or is there any better solution for this?
My code for this table:
<View style={stylesCustom.container}>
<FlatList
data={ data }
renderItem={({item}) =><View style={stylesCustom.GridViewBlockStyle}>
<Text style={styles.description} > {item.key} </Text></View>}
numColumns={5}
/>
</View>
const stylesCustom = StyleSheet.create({
container: {
justifyContent: 'center',
flex:1,
marginTop: 20
},
GridViewBlockStyle: {
justifyContent: 'center',
flex: 1,
alignItems: 'center',
backgroundColor: '#00BCD4',
borderWidth: 1,
borderColor: 'black'
},
GridViewInsideTextItemStyle: {
color: '#fff',
padding: 10,
fontSize: 18,
justifyContent: 'center',
},
}

How to align 2 react native elements, 1 being in the center and 1 on the beginning

Lets assume that we have those react native styles:
var styles = StyleSheet.create({
parentView:{
width: 400,
height:150
},
containerView:{
flex:1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor:'black'
},
child1:{
backgroundColor: 'red',
alignSelf: 'flex-start'
},
child2: {
backgroundColor: 'yellow'
}
}
and that we have this render function:
render: function(){
return(
<View style={styles.parentView}>
<View style={styles.containerView}>
<Text style={styles.child1}>Child1</Text>
<Text style={styles.child2}>Child2</Text>
</View>
</View>
);
}
This code produces this image:
but what I want to achieve is this image:
VERY VERY IMPORTANT: I want child2 to be TOTALLY centered within the containerView, and not a bit far to the right because of the space that child1 occupies.
How can I achieve that in react-native?*
p.s.: Keep in mind that this will run on many resolutions (many screens with different aspect ratios) thus, it cannot be set in an absolute way that would result on it only working on "some" screens but not on others.
not sure if this is the best way to do it, but it works for me
render() {
return(
<View style={styles.parentView}>
<View style={styles.containerView}>
<View style={styles.rowContainer}>
<View style={styles.rowItem}>
<Text style={styles.child1}>Child1</Text>
</View>
<View style={styles.rowItem}>
<Text style={styles.child2}>Child2</Text>
</View>
</View>
</View>
</View>
);
const styles = StyleSheet.create({
parentView:{
width: 400,
height:150
},
containerView:{
flex:1,
flexDirection: 'row',
alignItems: 'center',
backgroundColor:'black'
},
rowContainer: {
flex: 1,
flexDirection: 'column',
},
rowItem:{
flex: 1
},
child1:{
backgroundColor: 'red',
position: 'absolute',
},
child2: {
alignSelf: 'center',
backgroundColor: 'yellow'
}
});

Resources