make child 25% of width of parent flatlist react native - css

I have a flatlist containing between 1 - 4 children.
I want to give each child a width of 25% of the width of the container in this case the flatlist.
I have tried the following, but this results in the children having a width of 0.
How do i fix this.
<FlatList horizontal={true} style={welcome_style.favs_list} data={this.state.favorites} renderItem={(data: ListRenderItemInfo<GymSummary>) => {
return this.render_fav_gym(data.item);
}}></FlatList>
private render_fav_gym(data: GymSummary): JSX.Element {
return (
<TouchableOpacity style={{ width: "25%", aspectRatio: 1, padding: 10, backgroundColor: "blue", borderRadius: 14, marginHorizontal: 5 }}></TouchableOpacity>
);
}
const welcome_style = StyleSheet.create({
favs_list: {
width: "100%",
flex: 0,
backgroundColor: "red"
}
});

If the list has 1-4 items, and you always want all the items on screen, I would not recommend a FlatList. FlatLists are optimized for scrolling through long lists of items.
A simple View and the gap style should work for you. Here's one way you could do it. I added some Text inside the buttons, and you will probably have to change the styles to get the look you want.
<View style={welcome_style.favs_list}>
{this.state.favorites.map((_, index) => (
<TouchableOpacity style={welcome_style.button}>
<Text>{index + 1}</Text>
</TouchableOpacity>
)}
</View>
const welcome_style = StyleSheet.create({
favs_list: {
width: "100%",
backgroundColor: "red",
flexDirection: 'row',
gap: 5, // puts this much space between children
height: 48, // however tall you want the buttons to be here, plus padding
},
button: {
width: '25%',
aspectRatio: 1,
padding: 10,
backgroundColor: "blue",
borderRadius: 14,
justifyContent: 'center',
alignItems: 'center',
},
});

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.

Image inside a View element is not aligning to the right in React Native

I am implementing a tile in reactnative and I have to make the Image right in the tile just like this
What I want (click here)
and this is what I can implement till now
What I get ()
this is my code
<View style={styles.container} >
<Image
style={styles.image}
source={item.image}
resizeMode="cover"
/>
<View style={styles.overlay} />
<View style={styles.textContainer}>
<Text style={styles.subText}>{item.title}</Text>
<Text style={styles.headingText}>{item.message}</Text>
</View>
</View>
and this is style
const styles = StyleSheet.create({
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end',
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
marginTop: 20
},
image: {
width: COURSE_ITEM_WIDTH,
height: 120,
borderRadius: 10
},
textContainer: {
position: 'absolute',
left: 16,
flex: 1,
},
headingText: {
fontSize: 18,
color: '#ffffff',
marginTop: 5
},
subText: {
fontSize: 14,
color: '#ffffff',
},
timeText: {
fontSize: 15,
color: 'white',
textAlign: 'center',
marginTop: 5
},
overlay: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: '#206c72',
opacity: 0.6,
borderRadius: 10
}
})
Please help me i dont know what i am doing wrong. thanks in advance!
[note: please ignore the content, focus on alignment]
Your image is aligned to the right but there is nothing at the left of it. You should add flexDirection:'row' to the parent container and put an empty View with width : 40px before your image.
You can also remove the alignItems:flex-end and justifyContent:center from the main container
You can add alignSelf property to flex-end for image and image will be on end of the tile.
example 1:
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
alignSelf: "flex-end"
},
for reference i tried a sandbox example check it out here
also noticed you are using alignItems value twice first one is only necessary you can remove 2nd alignItems and position relative value from styles.container then it will align the image to end. you will get the exact result you want
example 2:
container: {
backgroundColor: '#206c72',
alignItems: 'flex-end', // only need this alignItems
borderRadius: 15,
width: COURSE_ITEM_WIDTH,
elevation: 7,
justifyContent: 'center',
marginTop: 20
},
image: {
width: "50%",
height: 120,
borderRadius: 10,
backgroundColor: "red", //for making sure how much space is taken by image you can remove on further
// no need of alignSelf to flex-end here
},

How can I arrange the flex items to occupy full width of the container?

I am trying to arrange 4 flex items in a flex row, the items have dynamic content, so the width can not be specified for the flex item.
is there any way for the flex items reduce their font size dynamically and occupy the full width of the container??
I was trying this in a sandbox and below code is cutting off the 4th row when the contents are not able to fit.
App Component:
function App() {
const a = [12, 1234, 123456, 123456789];
return (
<View style={styles.app}>
{a.map((element) => {
return (
<View style={styles.item}>
<Text style={[styles.text, { fontSize: 24 }]}>{element}</Text>
</View>
);
})}
</View>
);
}
Styles:
const styles = StyleSheet.create({
app: {
display: "flex",
backgroundColor: "black",
width: "100%",
height: "20%",
flexDirection: "row"
},
text: {
color: "white"
},
item: {
flexGrow: 0,
flexShrink: 0,
minWidth: "15%",
borderStartWidth: 1,
borderColor: "white",
justifyContent: "center",
padding: 5,
alignItems: "flex-start"
}
});
Screenshot:
You've set
flexGrow: 0,
flexShrink: 0,
This explicitly prevents the behaviour you're asking for. Removing both will default them to 1 and allow it to respond to available space.

How to have one image centered but another image in the top left corner?

I would like to create a header for my React Native app. It would have one primary image centered, and then a back button to the left of it (near the edge of the screen). At the moment, I am able to get them in the same row and have the primary image centered, but cannot figure out how to bring the back arrow image to the far left.
This is my code.
<View style={styles.container}>
<View style={styles.row}>
<Image style={styles.backarrow} source={require('./images/backarrow.png')} />
<Image style={styles.minilogo} source={require('./images/minibear.png')} />
</View>
</View>
And this is the style code.
container: {
flex: 1,
backgroundColor: '#5683C7',
alignItems: 'center',
justifyContent: 'center',
},
minilogo: {
height: 100,
width: 100,
},
backarrow: {
height: 50,
width: 40,
},
row: {
flexDirection: 'row',
margin: 15,
alignItems: 'center',
}
Ideally it would look like this
Any help would be greatly appreciated! Thanks.
using border width you can understand adjust your layout
apply this stylesheet
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#5683C7',
alignItems: 'center',
justifyContent: 'center',
flexDirection:"column"
},
minilogo: {
height: 100,
width: 100,
justifyContent:"flex-end",
flex:7,
},
backarrow: {
height: 50,
width: 40,
justifyContent:"flex-start",
alignSelf:"center",
flex:3,
},
row: {
flexDirection: 'row',
width:"100%",
margin: 1,
resizeMode:"stretch",
// backgroundColor:"green",
// borderWidth:1,
alignItems:"stretch",
}
});

Width and Height In react-native

please explain by what principle view sizes with element style are formed. I learned FlexBox however it breaks all my understanding.
code
export const App = () => {
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.element}>
<View style={styles.element1}></View>
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
backgroundColor: 'green',
},
element: {
// width: '100%',
// height: '100%',
backgroundColor: 'yellow',
// top: '5%',
},
element1: {
width: '50%',
height: '80%',
backgroundColor: 'red',
},
});
You can use flex: 1 instead of
width: '100%', height: '100%',.
The Flex: 1 means the component (In case, the view) have a priority value of 1, wich means, if there'snt another component on the same view with flex: 1, the component will take the entire screen.
If, there's two components with flex: 1, each one will take 50% of the entire screen.
Here's the documentation: React native flexbox

Resources