React Native <Text> overflows <View> when in a flex - react-native

So for the above image, I am attempting to get the "green" box to wrap around the dynamic text. Notice how the blue and yellow text boxes are in a flex: 'row' configuration, and the blue box of text is at a flex: 2 and the yellow is flex: 1.
Things work fine until the text is too big for the parent container.
I'd like for the green container to grow as needed to fit the flexed inner children. Is this possible with react native?
Here's an image of what it looks like in a web sense:
I've tried setting the green box to have a flex: 1 but then it's way too big as it fills the entire screen. Setting height is possible, but I don't know the size of the biggest inner component (at least without some hackery). I've even tried minHeight.
Has anyone attempted something like this? Do I need to get the height of the inner elements dynamically myself?
UPDATE - Here's the bit of code:
<View style={{ flex: 1, flexDirection: 'column', marginTop: 70, backgroundColor: '#f9e2ff' }}>
<View
style={{
minHeight: 40,
borderWidth: 1,
borderStyle: 'solid',
padding: 5,
margin: 5,
backgroundColor: '#58c09e'
}}
>
<View style={{ flex: 1, flexDirection: 'row' }}>
<View style={{ flex: 2, backgroundColor: '#eeff96' }}>
<Text>
Hello this is a long bit of text that will fill up the entire column to see how the text will wrap
</Text>
</View>
<View style={{ flex: 1, backgroundColor: '#eeffff' }}>
<Text>Hello again?</Text>
</View>
</View>
</View>
</View>
Thanks for looking.

Ok after looking around a bit more and reading: flex vs flexGrow vs flexShrink vs flexBasis in React Native? I was able to figure out the problem.
What I needed was flex: 0 on the row:
<View style={{ flex: 1, flexDirection: 'column', marginTop: 70, backgroundColor: '#f9e2ff' }}>
<View
style={{
minHeight: 40,
borderWidth: 1,
borderStyle: 'solid',
padding: 5,
margin: 5,
backgroundColor: '#58c09e'
}}
>
<View style={{ flex: 0, flexDirection: 'row' }}>
<View style={{ flex: 2, backgroundColor: '#eeff96' }}>
<Text>
Hello this is a long bit of text that will fill up the entire column to see how the text will wrap
</Text>
</View>
<View style={{ flex: 1, backgroundColor: '#eeffff' }}>
<Text>Hello again?</Text>
</View>
</View>
<View>
<Text>Here's another test</Text>
</View>
</View>
</View>
This produces what I would expect:
So I guess the flexbox doesn't "work[s] the same way in React Native as it does in CSS on the web" like they state in their documentation.

Try This Coode -->
<View style={{flex:1,flexDirection:'row',borderWidth:1,padding:5}}>
<View style={{flex:0.7}}>
<Text>
Hello This is long bit of text that will fill up the entire
column to see how the text will wrap
</Text>
</View>
<View style={{flex:0.3}}>
<Text>Hello Again</Text>
</View>
</View>

Related

react-native uwp - align text elements in column with right side of label

With react-native for windows UWP I have the following JSX:
<View style={{ flexDirection: "row" }}>
<View style={{ flex: 1, flexDirection: 'column', margin: 5, alignItems: 'stretch' }}>
<View style={{ flexDirection: 'row' }}>
<Text selectable={true} style={{ textAlign: 'right', flex: 1 }}>Average:</Text>
<Text selectable={true} style={{ flex: 2 }} > {this.props.averageValue} C</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<Text selectable={true} style={{ textAlign: 'right', flex: 1 }}>Last:</Text>
<Text selectable={true} style={{ flex: 2 }}> {this.props.lastValue} C</Text>
</View>
</View>
</View>
Which lays out the Average and Last text so they're aligned with the colons like so:
Visually this is what I want, but I can't select the text of an entire line at once. Only each individual text element is selectable. If I wrap the two text blocks with an outer text block like this:
<View style={{ flexDirection: 'row' }}>
<Text selectable={true}>
<Text style={{ textAlign: 'right', flex: 1 }}>Average:</Text>
<Text style={{ flex: 2 }} > {this.props.averageValue} C</Text>
</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<Text selectable={true}>
<Text style={{ textAlign: 'right', flex: 1 }}>Last:</Text>
<Text style={{ flex: 2 }}> {this.props.lastValue} C</Text>
</Text>
</View>
Then my text is selectable like I want, but the layout changes to this:
How can I get the layout I want and all of the text to be selectable? Do I have to use explicit widths or can this be done with flexbox?
This doesn't appear to be possible. The only way to make them all selectable is to wrap them in an outer Text element. However text boxes do not participate in Flexbox layout so the alignment I want cannot be achieved.

flex not working in ScrollView in react-native

I have a very basic styling question in react native
below is my code:
[![return (
<View style={{ flex: 1, backgroundColor: "blue" }}>
<ScrollView style={{ flex: 1, backgroundColor: "blue" }}>
<View style={{ flex: 1, backgroundColor: "red" }}>
<Text>Hello</Text>
</View>
<View style={{ flex: 1, backgroundColor: "orange" }}>
<Text>Hello</Text>
</View>
<View style={{ flex: 1, backgroundColor: "green" }}>
<Text>Hello</Text>
</View>
</ScrollView>
<ScrollView style={{ flex: 1, backgroundColor: "blue" }}>
<View style={{ flex: 1, backgroundColor: "red" }}>
<Text>Hello</Text>
</View>
<View style={{ flex: 1, backgroundColor: "orange" }}>
<Text>Hello</Text>
</View>
<View style={{ flex: 1, backgroundColor: "green" }}>
<Text>Hello</Text>
</View>
</ScrollView>
</View>
);
I just want to know why am I getting blue space between 2 ScrollVie? If I remove ScrollView then my flex property is working fine.
Change your ScrollView to:
<ScrollView
... other stuff
// Add here
contentContainerStyle={{
flex: 1 // or flexGrow: 1
}}
>
Issue on React Native repo
The styles you are passings to the ScrollView should be passed in the ScrollView Container
like this
<ScrollView
contentContainerStyle={{
flex: 1 // or flexGrow: 1
}}
> ... </ScrollView >
this can help you to understand
The reason is that you are giving flex:1 for the parent view So it takes a maximum screen height. And also the child ScrollViews has flex: 1. If you change the background color of the scroll view to some other color you can notice that it is the scrollView that is stretched and not the Parent View.
You can remove the flex property of the parent view so that your ScrollView will not be stretched to take up half the screen.

React-Native Flexbox - Position One Item at Vertical Center and other at Bottom

Within a parent view, I would like to vertically center align one piece of text and have another at the bottom of the view.Whenever I add the bottom text, it shifts the position of the vertical centered view upwards (to make it the vertical center of the remaining space).
How do I keep the text vertically centered align relative to the parent view?
Update: I understand I can do this using {position: 'absolute',
bottom:0}, but want to understand the flex-box solution.
<View style={{height: 300, borderColor: "black", borderWidth: 1}}>
<View style={{ justifyContent: "center", flex: 1 }}>
<Text>Vert Middle</Text>
</View>
<View>
<Text>Vert Bottom</Text>
</View>
</View>
Just try below code
<View style={{height: 300, borderColor: "balck", borderWidth: 1}}>
<View style={{ backgroundColor: 'red', justifyContent: "center", flex: 1 }}>
<Text>Vert Middle</Text>
</View>
<View style={{position: 'absolute', bottom: 0}}> // Here is your updations
<Text>Vert Bottom</Text>
</View>
</View>
This is going to work for you. Also #Nitish answer is going to work too.
render() {
return (
<View style={{
height: 300,
borderColor: "black",
borderWidth: 1
}}>
<View style={{
justifyContent: "center",
flex: 1
}}>
<Text>Vert Middle</Text>
</View>
<View style={{
height:0, //Here...
justifyContent: "flex-end",
}}>
<Text>Vert Bottom</Text>
</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>

Why are these React components overlapping?

I rendered two similar components. Each component has an icon and text, and each of them should not be overlapping. What's wrong with my styling?
import Icon from "react-native-elements/src/icons/Icon";
<TouchableOpacity onPress={_ => playSound(audio)} style={{
flexDirection: 'row',
flexGrow:1,
flex: 1
}}>
<View>
<Icon name="volume-up" color={PRIMARY_BG} size={24}/>
</View>
<View>
<Text style={{
flexGrow: 1,
fontSize: 8,
backgroundColor: GRAY
}}>
[{locale}]{this.props.pronunciation[locale][0]}
</Text>
</View>
</TouchableOpacity>
Here's the output:
Parent container style
headItemContent: {
flex: 3,
flexDirection: 'row',
justifyContent: 'space-between'
},
I am not sure where your images are meant to be, but the problem is the flexDirection you have set. The flexDirection on the touchableOpacity should be column:
flexDirection: "column"
Since yours is row, the images and text are rendering beside each other. There is not enough space so they are over lapping. So change the flexDirection and that should fix it.
Edit - Or add flex to your image and text:
<View style={{flex: 1}}>
<Icon name="volume-up" color={PRIMARY_BG} size={24}/>
</View>
<View style={{flex: 1}}>
<Text style={{
flexGrow: 1,
fontSize: 8,
backgroundColor: GRAY
}}>
[{locale}]{this.props.pronunciation[locale][0]}
</Text>
</View>
Let me know if that helps!