react-native中的StickeyListView其实就是带Section的UITableView。
参考:http://moduscreate.com/react-native-listview-with-section-headers/,
原理就是二维数组。
下面是代码的实现:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
TouchableOpacity,
ActivityIndicatorIOS
} from 'react-native';
var API_URL = 'http://demo9383702.mockable.io/users';
class StickeyListViewDemo extends Component {
constructor(props) {
super(props);
var getSectionData = (dataBlob,sectinoID) => {
return dataBlob[sectionID];
};
var getRowData = (dataBlob,sectionID,rowID) => {
return dataBlob[sectionID + ':' + rowID];
};
this.state = {
loaded:false,
dataSource: new ListView.DataSource({
getSectionData: getSectionData,
getRowData: getRowData,
rowHasChanged:(row1,row2) => row1 !== row2,
sectionHeaderHasChanged:(s1,s2) => s1 !== s2
})
};
}
render() {
if (!this.state.loaded) {
return this.renderLoadingView();
}
return this.renderListView();
}
renderLoadingView() {
return (
<View style={[styles.header]}>
<Text style={[styles.headerText]}>User List</Text>
<View>
<ActivityIndicatorIOS
animating = {!this.state.loaded}
style={[styles.activityIndicator,{height: 80}]}
size='large'
/>
</View>
</View>
);
}
renderListView() {
return (
<View style={[styles.container]}>
<View style={[styles.header]}>
<Text style={[styles.headerText]}>User List</Text>
</View>
<ListView
dataSource={this.state.dataSource}
style={[styles.listView]}
renderRow={this.renderRow.bind(this)}
renderSectionHeader={this.renderSectionHeader.bind(this)}
/>
</View>
);
}
renderSectionHeader(sectionData,sectionID) {
return (
<View style={[styles.section]}>
<Text style={[styles.text]}>{sectionData}</Text>
</View>
);
}
renderRow(rowData,sectionID,rowID) {
return (
<TouchableOpacity onPress={this.onPressRow.bind(this,rowData)}>
<View style={[styles.rowStyle]}>
<Text style={[styles.rowText]}>{rowData.name.title} {rowData.name.first} {rowData.name.last}</Text>
</View>
</TouchableOpacity>
);
}
onPressRow(rowData,sectionID) {
alert(rowData.email);
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(API_URL).then((response) => response.json()).then((responseData) => {
var orgainzations = responseData.results,
length = orgainzations.length,
dataBlob = {},
sectionIDs = [],
rowIDs = [],
organization,
users,
userLength,
user,
i,
j;
for(i=0;i<length;i++) {
organization = orgainzations[i];
sectionIDs.push(organization.id);
dataBlob[organization.id] = organization.organization;
users = organization.users;
userLength = users.length;
rowIDs[i] = [];
for(j=0;j<userLength;j++) {
user = users[j].user;
rowIDs[i].push(user.md5);
dataBlob[organization.id + ':' + user.md5] = user;
}
}
this.setState({
dataSource:this.state.dataSource.cloneWithRowsAndSections(dataBlob,sectionIDs,rowIDs),
loaded:true
});
console.log('dataBlob is' + dataBlob);
console.log('sectionIDs is' + sectionIDs);
console.log('rowIDs is' + rowIDs)
}).done();
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
activityIndicator: {
alignItems:'center',
justifyContent:'center'
},
header: {
height:60,
justifyContent:'center',
alignItems:'center',
backgroundColor:'#3F51B5',
flexDirection: 'column',
paddingTop: 25
},
headerText: {
fontWeight: 'bold',
fontSize: 20,
color: 'white'
},
text: {
color: 'white',
//paddingHorizontal: 8,
fontSize: 16
},
rowStyle: {
paddingVertical: 20,
paddingLeft: 16,
borderTopColor: 'white',
borderLeftColor: 'white',
borderRightColor: 'white',
borderBottomColor: '#E0E0E0',
borderWidth: 1
},
rowText: {
color: '#212121',
fontSize: 16
},
subText: {
fontSize: 14,
color: '#757575'
},
section: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'flex-start',
paddingLeft: 6,
backgroundColor: '#2196F3'
},
listView: {
flex:1
}
});
AppRegistry.registerComponent('StickeyListViewDemo', () => StickeyListViewDemo);