Ataomega Ataomega - 1 month ago 8
React JSX Question

Listview with flexbox showing all items in one row

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>
);
}
}




Answer

Here are a couple of general CSS / Flexbox concepts that may help identify the problem:

An initial setting of a flex container is flex-direction: row, meaning items will align horizontally. For vertical alignment, override the default with flex-direction: column.

NOTE: Although row is the default in CSS, column is the default in React Native.

Another initial setting is flex-wrap: nowrap (in both CSS and RN). This means items will remain in a single line. To create a multi-line flex container, override the default with flex-wrap: wrap.

Note that when you switch flex-direction, keyword alignment properties such as align-items and justify-content, switch direction, as well.

More details: In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?