JamesTheHunt
JamesTheHunt

Reputation: 105

React Native Align Self Flex End not working as expected

Pretty simple one, looking to align some text on the left, and some on the right. For this I thought I'd use flexbox with the following code:

return (
<TouchableOpacity disabled={isLoading}>
  <View style={styles.container}>
    <View style={styles.venueImageContainer}>
      {isLoading ? (
        <Loader />
      ) : (
        <Image style={styles.venueImage} source={ { uri: getImage()} } />
      )}
    </View>
    <View style={{flexDirection: 'row', backgroundColor: 'red'}}>
      <View style={{alignSelf: 'flex-start', backgroundColor: 'blue'}}>
        <Text style={styles.venueName}>{venue.name}</Text>
      </View>
      <View style={{alignSelf: 'flex-end', backgroundColor: 'green'}}>
        <Text style={styles.personCount}>Test</Text>
      </View>
    </View>
  </View>
</TouchableOpacity>)

The only styles being referred to via 'Styles.' are for the text color and size. So nothing that could interfere with the flex layout.

So ideally, I'd like I want "Text1" on the far left, and then "Text2" on the far right, but instead I am getting this: Image showing flexbox error

So the parent container gets full width, but the children are not aligning themselves by flex-start or flex-end.

I am new to React / React Native so please go easy on me...

Cheers guys :)

Upvotes: 6

Views: 9512

Answers (5)

bieboebap
bieboebap

Reputation: 300

So rather than using 'space-between' as everyone is suggesting (which is just a workaround..), this is the solution: You have to add "flex:1" in the style where you specify flex-start and flex-end.

return (
<TouchableOpacity disabled={isLoading}>
  <View style={styles.container}>
    <View style={styles.venueImageContainer}>
      {isLoading ? (
        <Loader />
      ) : (
        <Image style={styles.venueImage} source={ { uri: getImage()} } />
      )}
    </View>
    <View style={{flexDirection: 'row', backgroundColor: 'red', flex:1}}>
      <View style={{alignSelf: 'flex-start', backgroundColor: 'blue', flex:1}}>
        <Text style={styles.venueName}>{venue.name}</Text>
      </View>
      <View style={{alignSelf: 'flex-end', backgroundColor: 'green', flex:1}}>
        <Text style={styles.personCount}>Test</Text>
      </View>
    </View>
  </View>
</TouchableOpacity>)

Upvotes: 4

BenoHiT
BenoHiT

Reputation: 312

had some struggles to align the items at the end, but

justifyContent: 'flex-end' 

finally worked

Upvotes: 0

Maybe it means the end of the red view it's on the end of the green view itself. Put a alignSelf: 'stretch' on the red view, like as follow:

return (
<TouchableOpacity disabled={isLoading}>
  <View style={styles.container}>
    <View style={styles.venueImageContainer}>
      {isLoading ? (
        <Loader />
      ) : (
        <Image style={styles.venueImage} source={ { uri: getImage()} } />
      )}
    </View>
    <View style={{flexDirection: 'row', backgroundColor: 'red', alignSelf: 'stretch'}}>
      <View style={{alignSelf: 'flex-start', backgroundColor: 'blue'}}>
        <Text style={styles.venueName}>{venue.name}</Text>
      </View>
      <View style={{alignSelf: 'flex-end', backgroundColor: 'green'}}>
        <Text style={styles.personCount}>Test</Text>
      </View>
    </View>
  </View>
</TouchableOpacity>)

Or you can use position: 'absolute on the green view to change it's position with some fixed values, like as follow:

return (
<TouchableOpacity disabled={isLoading}>
  <View style={styles.container}>
    <View style={styles.venueImageContainer}>
      {isLoading ? (
        <Loader />
      ) : (
        <Image style={styles.venueImage} source={ { uri: getImage()} } />
      )}
    </View>
    <View style={{flexDirection: 'row', backgroundColor: 'red'}}>
      <View style={{alignSelf: 'flex-start', backgroundColor: 'blue'}}>
        <Text style={styles.venueName}>{venue.name}</Text>
      </View>
      <View style={{backgroundColor: 'green', position: 'absolute', right: 10}}>
        <Text style={styles.personCount}>Test</Text>
      </View>
    </View>
  </View>
</TouchableOpacity>)

Change the right: 10 value to match your needs.

or put a justifyContent: 'space-between' on the red view, like as follow:

return (
<TouchableOpacity disabled={isLoading}>
  <View style={styles.container}>
    <View style={styles.venueImageContainer}>
      {isLoading ? (
        <Loader />
      ) : (
        <Image style={styles.venueImage} source={ { uri: getImage()} } />
      )}
    </View>
    <View style={{flexDirection: 'row', backgroundColor: 'red', justifyContent: 'space-between'}}>
      <View style={{alignSelf: 'flex-start', backgroundColor: 'blue'}}>
        <Text style={styles.venueName}>{venue.name}</Text>
      </View>
      <View style={{alignSelf: 'flex-end', backgroundColor: 'green'}}>
        <Text style={styles.personCount}>Test</Text>
      </View>
    </View>
  </View>
</TouchableOpacity>)

but if you want to have more than 2 views inside that red view, one of them would be in the middle, so i dont think you would want that.

(I dont know why your red view stretch's all the way to the end of the view, but it shouldn't, i think (I may be wrong about this))

Upvotes: 1

A. Ecrubit
A. Ecrubit

Reputation: 609

Your solution doesn't work because the CSS property align-self is used for the cross axis and alignSelf works the same way so it can't be used to align horizontally which is here the main axis.

  1. First solution : use justifyContent: space-between it works perfectly for your case :
<View style={{ flexDirection: 'row', backgroundColor: 'red', justifyContent: 'space-between' }}>
                    <View style={{backgroundColor: 'blue' }}>
                        <Text>Left</Text>
                    </View>
                    <View style={{backgroundColor: 'green' }}>
                        <Text>Right</Text>
                    </View>
</View>
  1. Second solution : use a View with flex: 1 to "fill" the middle space :
<View style={{ flexDirection: 'row', backgroundColor: 'red' }}>
                    <View style={{ backgroundColor: 'blue' }}>
                        <Text>Left</Text>
                    </View>
                    <View style={{flex: 1}}></View>
                    <View style={{ backgroundColor: 'green' }}>
                        <Text>Right</Text>
                    </View>
 </View>

Upvotes: -1

Michael Benjamin
Michael Benjamin

Reputation: 371043

Have you tried space-between?

<View style={{flexDirection:'row', justifyContent:'space-between', backgroundColor:'red'}}>

Upvotes: 4

Related Questions