I am displaying a FlatList with variable number of items and the last item always is not visible completely (border bottom).
render()
render() {
return (
<View style={styles.container}>
<FlatList style={styles.list} containContainerStyle={{paddingBottom: 20}}
...
/>
</View>
);
}
CSS
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
},
list: {
flex: 1,
width: "95%"
}
You are using a wrong style property for the flat list, it is contentContainerStyle not containContainerStyle. You will have to increase it according to the size of your item.
<FlatList contentContainerStyle={{ paddingBottom: 20}} />
Related
I'm trying to get space around my items in a horizontal flatlist, no matter how I try it doesn't seem to work:
const renderItem = ({item}) => {
return (
<View style={styles.item}>
<Image
source={{uri: content.uri}}
style={styles.image}
/>
<View>
<Text style={styles.contentTitle}>{content.title}</Text>
<Text style={styles.contentText}>{content.releaseDate}</Text>
</View>
</View>
)
}
<View style={styles.container}>
{header}
<View style={{width: '100%', justifyContent: 'space-around', backgroundColor: 'green'}}>
<FlatList
data={data}
pagingEnabled={true}
horizontal={true}
renderItem={renderItem}
keyExtractor={item => item.id}
ref={flatList}
/>
</View>
</View>
const styles = StyleSheet.create({
container: {
width: windowWidth,
marginTop: 15,
paddingBottom: 15,
borderBottomWidth: 1,
borderBottomColor: Colors.borderBlue,
backgroundColor: Colors.backgroundGenericTransparent,
},
item: {
width: windowWidth / 3.1,
backgroundColor: 'red',
},
image: {
width: '100%',
height: 220,
},
})
result:
As you can see the items are all together on the left even though I have added a space-around property on the container. Not show how I can resolve this.
use ItemSeparatorComponent
<FlatList
data={data}
pagingEnabled={true}
horizontal={true}
renderItem={renderItem}
keyExtractor={item => item.id}
ref={flatList}
ItemSeparatorComponent={() => {
return (
<View
style={{
height: "100%",
width: 10,
}} />
);
}}
/>
Use this prop on flatlist:
columnWrapperStyle={{ justifyContent: "space-between" }}
Not sure what you are trying to achieve.
Is that what you want?
snack here
Just add horizontal padding to your container. and no matter how big your items get you will always have spacing left and right. If the item gets too big you can start to scroll.
<View style={styles.messageGalleryContainer}>
<FlatList
data={files}
renderItem={renderImageGalleryItem}
keyExtractor={(item) => item?._id}
horizontal
showsHorizontalScrollIndicator={false}
ItemSeparatorComponent={() => <View style={{ width: 10 }} />} // add this line
contentContainerStyle={styles.messageGalleryItemContainer}
/>
</View>
You should use ItemSeparatorComponent with an empty component or with any element you want.
I have written following code but my flex under 'titleContainer' is not working.
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 0.5,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
Please see the screen shot. The green background should cover half of the screen.
Its resolved now!
Actually this component was getting displayed conditionally. There was an issue with that condition. I have fixed that and everything worked.
Flex in RN only take interger value
In case you want titleContainer take 50% size of container by using flex, This is how you can achieve that.
You need another view the take the same flex value with titleContainer, so titleContainer and that dump view will take 50% size of parent view each
export const Focus = () => {
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>What would you like to focus on?</Text>
<TextInput />
</View>
<View style={{flex: 1}} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#43840',
},
titleContainer: {
flex: 1,
padding: 16,
justifyContent: 'center',
backgroundColor: '#559974',
},
title: {
color: 'white',
fontWeight: 'bold',
fontSize: 15,
},
});
To use flex property on child tag your parent tag needs to have a display: "flex" property on it.
container: {
display: 'flex',
flexDirection: 'column',
flex: 1,
backgroundColor: '#43840',
},
I want my app to add text underneath the goal section but flex is not letting me do that even if I create new components in native P.S Still a beginner
import React, { useState } from "react";
import { StyleSheet, View, TextInput, Button, Text } from "react-native";
export default function App() {
return (
<View style={styles.Container}>
<View style={styles.GoalInp}>
<TextInput
placeholder="Course Goal"
style={{ overflow: "scroll" }}
onChangeText={goalInputHandler}
value={enteredGoal}
/>
</View>
<View>
<Button title="ADD" onPress={addGoalHandler} />
</View>
<View>
{couseGoals.map(goal => (
<Text>{goal}</Text>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
Container: {
padding: 50,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
},
GoalInp: {
borderWidth: 1,
width: "80%",
padding: 10,
borderColor: "black"
}
});
You need to bring the listing outside the Container View, as the flex-direction of Container is row, all items will be in a row including form.
My modified code is given below
<View style={styles.wrapper}>
<View style={styles.Container}>
<View style={styles.GoalInp}>
<TextInput
placeholder="Course Goal"
style={{ overflow: "scroll" }}
/>
</View>
<View>
<Button title="ADD" onPress={this.addGoalHandler} />
</View>
</View>
<View>
{this.state.couseGoals.map(goal => (
<Text>{goal}</Text>
))}
</View>
</View>
const styles = StyleSheet.create({
wrapper:{
flex:1,
},
Container: {
padding: 50,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center"
},
GoalInp: {
borderWidth: 1,
width: "80%",
padding: 10,
borderColor: "black"
},
});
I think that you use to much Vieuw elements.
You should for example use a Text for where your text need to print out.
But I think I have it.
You wrapped everything into a View with a style of;
flexDirection: "row",
Not that good if you don't want to have the whole View on one line....
Issue solved?
I have the following code:
renderActionButtons(actionButtons){
let actionButtonsContent = actionButtons.map((button, i) => {
return <TouchableHighlight key={i} onPress={() => {this.updateConversation(button);}} style={globalStyle.actionButton} underlayColor='#f1f1f1'>
<View key={i}>
<Text style= {globalStyle.actionButtonText}>{ button }</Text>
</View>
</TouchableHighlight>
})
return actionButtonsContent
}
renderConversations(){
let conversationContent = this.state.conversationArray.map((convObj, i) => {
return <View key={i} style={[globalStyle.conversationContainer,globalStyle.shadow,convObj.directionClass]}>
<Text style= {[globalStyle.conversationText,convObj.directionTextClass]}>{ convObj.text }</Text>
<View style= {globalStyle.actionButtonsContainer}>
{ this.renderActionButtons(convObj.actionButtons) }
</View>
</View>
})
return conversationContent
}
This is to render the following view:
I'm trying to wrap those pills inside the white container.
Following are the styles I have used:
conversationContainer:{
maxWidth:310,
backgroundColor: 'white',
borderBottomRightRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 0,
borderTopLeftRadius: 10,
padding: 10,
marginTop: 10
},
actionButtonsContainer:{
flex:1,
flexDirection: 'row',
paddingTop: 10
},
actionButton:{
backgroundColor:primaryRed,
borderRadius:30,
padding: 7,
marginRight: 10
},
actionButtonText:{
color:'white',
fontSize:12,
alignSelf: 'center'
},
How can I wrap the child Elements inside the parent element so that it doesn't overflow like show in picture ?
With flexbox, you have the flexWrap property, it defines whether the flex items are forced in a single line or can be wrapped. By default it's set to nowrap. Set it to wrap:
actionButtonsContainer:{
flex:1,
flexDirection: 'row',
flexWrap: 'wrap',
paddingTop: 10
},
I have a problem styling with FlexBox.
In my code below, there is a listview with section headers. Each section header has items under it.
The problem is, all items are shown in one row. How can I fix it? I tried adding width 100% for each row but it didn't work.
Thanks in Advance!
var styles = StyleSheet.create({
// Default Loading View
loading: {
alignItems: 'center',
backgroundColor: '#FFFFFF',
flex: 1,
//fontFamily: 'Rokkitt',
justifyContent: 'center',
padding: 5,
paddingTop: 40,
},
// Table
listView: {
backgroundColor: '#FFFFFF',
paddingTop: 60,
},
// Table Row
rowContainer: {
flexDirection: 'row',
padding: 20,
},
// Text wrapper within row
textContainer: {
flex: 1
},
// Row separator
separator: {
height: 1,
backgroundColor: '#E3E0D7'
},
// Row Post Title
title: {
color: '#3D728E',
//fontFamily: 'Rokkitt',
fontSize: 20,
},
// Row Post Description
description: {
color: '#7C705F',
//fontFamily: 'Josefin Sans',
fontSize: 14,
lineHeight: 20,
marginTop: 8,
textAlign: 'left',
},
});
class Courses extends Component {
render() {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return (
<View style={{
flex: 1
}}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
style={styles.listView}
/>
</View>
);
}
renderRow(data) {
var rowPress = () => {
console.log('row pressed');
};
var header = (
<View>
<View style={styles.rowContainer}>
<View style={styles.textContainer}>
<Text style={styles.title}>{data.nid}</Text>
<Text style={styles.description} numberOfLines={0}>{data.title}</Text>
</View>
</View>
<View style={styles.separator}></View>
</View>
);
///////////
var content = [];
for(var x=0; x < Object.keys(data.course).length; x++){
content.push(
<TouchableHighlight
underlayColor='#e3e0d7'
key={x}
onPress={rowPress()}
>
<Text style={{
flex: 1,
flexDirection: 'column',
flexWrap: 'wrap',
}}>{data.course[x].title}</Text>
</TouchableHighlight>
);
}
var clist = (
<View style={styles.rowContainer}>
{content}
</View>
);
////////////
return (
<Accordion
header={header}
content={clist} //// <<< Problem! contents are shown in one line, i need each item to wrap whole line>>>
easing="easeOutCubic"
/>
);
}
renderLoadingView() {
return (
<View style={styles.loading}>
<Text style={styles.loading}>
Fetching Courses, please wait...
</Text>
</View>
);
}
}
Below are a couple of general CSS / Flexbox concepts that may help identify the problem.
In standard CSS, the initial value of flex-direction is row. This means that items will line up horizontally. For vertical alignment, override the default with flex-direction: column.
However, in React Native, the default flex-direction is column.
https://facebook.github.io/react-native/docs/flexbox.html#flex-direction
Note that when you switch flex-direction, keyword alignment properties such as align-items and justify-content, switch directions, as well.
Another flexbox initial setting (in both CSS and React) is flex-wrap: nowrap.
This means items will remain in a single line.
To create a multi-line flex container, override the default with flex-wrap: wrap.