let icons=require('./mockdata/icons.json').data; constructor(props){ super(props); let dataSource = new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2}); this.state={ iconSource:dataSource.cloneWithRows(icons), } }
其中{rowHasChaged:(r1,r2)=>r1!==r2},是告诉ListView当数据源变化时再重新渲染。
2、在页面使用<ListView>,设置数据源dataSource,内部样式contentContainerStyle,每个元素的渲染方式renderRow为renderIcon
<ListView dataSource={this.state.iconSource} contentContainerStyle={styles.iconList} renderRow={this.renderIcon} />
3、实现渲染函数renderIcon,默认传入四个参数:
rowData:每个元素对应的数据
sectionId:元素所属分区
rowId:元素的id
highlightRow:通过调用此方法可以使某一行处于高亮
在renderIcon函数中定义每一个icon图标的渲染的方式,并返回JSX:
renderIcon(rowData,sectionId,rowId,highlightRow){ return( <TouchableOpacity activeOpacity={0.5}> <View key={rowId} style={styles.iconItem}> <Image style={styles.iconImg} source={{uri:'mipmap/'+rowData.image}} /> <Text style={styles.iconTitle}>{rowData.title}</Text> </View> </TouchableOpacity> ) }
3、使用ListView渲染二维数据以上例子中的data是个一维数组,数组每个元素中包含title与image两个字段,如果data是个二维数组,例如
其中data数组的一维元素中包含title与cars,而cars又是一个数组。使用ListView将其渲染为上面右图所示按首字母分类的列表。
存储原理:
ListView使用DataBlob来存储二维数据,其结构如下:
DataBlob按照一定的格式组织二维数据,如上左图。DataBlob首先存储数组的第一维section并为其分配ID,例如将上面的一维数组的"title":"A",存储为DataBlob[0]="title":"A",分配sectionID为0,"title":"B",存储为DataBlob[1]="title":"B",分配ID为1......以此类推。
之后再存储数组的第二维row,例如"cars":[{"name":"奥迪","icon": "m_9_100.png"}],它的第一维sectionID为0,第二维rowID为2,将其存储为DataBlob[0:2]={"name":"奥迪","icon": "m_9_100.png"}。
ListView使用步骤如下:
1、设置数据源
与一维ListView使用类似,首先在constructor中设置state为DataSource对象:
this.state={ carData:new ListView.DataSource({ getSectionData:(dataBlob,sectionID)=>dataBlob[sectionID], //设置sectionData获取方式 getRowData:(dataBlob,sectionID,rowID)=>dataBlob[sectionID+':'+rowID], //设置rowData获取方式 sectionHeaderHasChanged:(s1,s2)=>s1!==s2, //设置section更新方式 rowHasChanged:(r1,r2)=>r1!==r2 //设置row更新方式 }) }
在新建DataSource对象时需要传递四个函数参数
getSectionData:定义获取section的方式,它接收两个参数,dataBlob对象与sectionId,例如要获取上面提到的DataBlob[0]="title":"A" ,则通过dataBlob[sectionID]就可以返回"title":"A"。
getRowData:获取row的方式,同理,通过DataBlob[0:2]可以得到{"name":"奥迪","icon": "m_9_100.png"}
sectionHeaderHasChanged:定义section什么时候更新,接收两个参数s1,s2分别为前后两个状态,不同时才会重新渲染section
rowHasChanged:定义row什么时候更新
2、在页面中使用ListView
使用List View时设置其数据源及渲染方法
<ListView style={styles.carList} dataSource={this.state.carData} //定义数据源 renderRow={this.renderCarRow} //定义row的渲染方法 renderSectionHeader={this.renderCarSection} //定义SectionHeader渲染方法 />
3、实现渲染方法,方法默认会传入参数rowData与sectionData
renderCarSection(sectionData){ return( <View style={styles.sectionBar}> <Text style={styles.sectionTxt}>{sectionData}</Text> </View> ) } renderCarRow(rowData){ return( <TouchableOpacity activeOpacity={0.5}> <View style={styles.carItem}> <Image source={{uri:'asset:/cars/'+rowData.icon}} style={styles.carImg} /> <Text style={styles.carTitle}>{rowData.name}</Text> </View> </TouchableOpacity> ) }
4、将数据放入dataBlob
在组件挂载完成后将数据按照格式放入dataBlob并更新数据源,使数据加载到页面