ListView
創建文檔時間:2016.3.23-09:18
作者:三月懶驢
使用平臺:Mac
作用
ListView在APP的作用可謂是重中之重,除非你不需要要多信息展示,否則的話,一個APP肯定是要用ListView來工作的。而優化它,也是必須的。
簡單代碼
'use strict'
import React from 'react-native'
let {Component,StyleSheet,View,Text,ListView} = React;
class List extends Component{
constructor(props){
super(props)
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row 1']),
};
}
renderRow(rowData){
return <Text>{rowData}</Text>
}
render(){
return (
<ListView
style={styles.body}
dataSource={this.state.dataSource}
renderRow={this.renderRow} />
);
}
}
const styles = {
body:{
flex:1,
},
}
export default List
一個簡單的ListView
一個ListView的最簡單參數有兩個:
一個是dataSource:數據源,
另外一個是renderRow,渲染每一行的動作。
-
先簡單看看:初始化一個數據源
let ds = new ListView.DataSource();
-
里面的參數:后面是ES6語法的箭頭函數,就是為rowHasChanged定義一個函數
rowHasChanged: (r1, r2) => r1 !== r2
-
下面把數據填入初始化的數據源去。
dataSource: ds.cloneWithRows(['row 1']),
renderRow
傳來的參數有:rowData, sectionID, rowID, highlightRow
這里主要用了rowData,也就是我們剛才填進去的數據:一個數組
由上面可以看到,我們先定義一個數據源,就是一個數組,這個數組就會在renderRow的時候,以rowData傳入。傳入之后我們可以把它渲染出來,至于渲染的樣式的話,可以自己寫,看方法: renderRow
Section
API里面木有細說這個東西,不過看例子的話,我們可以看到官方的例子里面不是像我們這樣寫的
//我們的寫法
this.state = {
dataSource: ds.cloneWithRows(['row 1']),
};
//官方
this.state = {
dataSource: ds.而是cloneWithRowsAndSections(['row 1']),
};
cloneWithRows & cloneWithRowsAndSections。那么這兩個有什么不同?什么又是Sections!如果你是一個前端的話,你會很簡單明白Section!其實就是表頭,以前用Table標簽一樣也有表頭這個東西。而在IOS里面,表頭在滾動到頂部的時候會附在頂部。我們這里稱之為Section。官方木有很多的文檔去說明它,但是用起來的時候很簡單。
在木有Section的時候,我們只需提供一個數組過去就行,而當你需要表頭的時候,你需要提供的是一個對象!
下面舉個例子:
//木有Section的時候
var data = [1,2,3,4,5,6]
//有Section的時候
var data = {
'section1':[1,2,4,5,6],
'section2':[1,2,4,5,6],
}
'use strict'
import React from 'react-native'
let {Component,StyleSheet,View,Text,ListView} = React;
/*renderSectionHeader*/
class List extends Component{
constructor(props){
super(props)
let ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
sectionHeaderHasChanged: (s1, s2) => s1 !== s2
});
this.state = {
dataSource: ds.cloneWithRowsAndSections(this.getRows()),
};
}
getRows(){
let dataObj = {}
let section = '測試1'
dataObj[section] = []
for (let i=0;i<10;i++){
let data = {
name:'第'+i+'行',
num:i
}
dataObj[section][i] = data
}
section = '測試2'
dataObj[section] = []
for (let i=0;i<10;i++){
let data = {
name:'第'+i+'行',
num:i
}
dataObj[section][i] = data
}
return dataObj
}
renderRow(rowData,sectionID,rowID,highlightRow){
console.log(sectionID);
return (
<View style={styles.rowItem}>
<View style={styles.rowItemLeft}>
<Text style={styles.rowItemText}>{rowData.name}</Text>
</View>
<View style={styles.rowItemRight}>
<Text style={styles.rowItemText}>數據:{rowData.num}</Text>
</View>
</View>
)
}
onEndReached(e){
//console.log(e)
}
renderSectionHeader(sectionData, sectionID){
console.log(sectionData)
return(
<View style={styles.rowTite}>
<Text>{sectionID}</Text>
</View>
)
}
onChangeVisibleRows(visibleRows, changedRows){
//console.log(visibleRows)
}
render(){
return (
<ListView
style={styles.body}
onEndReached = {this.onEndReached}
onEndReachedThreshold = {20}
renderSectionHeader = {this.renderSectionHeader}
onChangeVisibleRows = {this.onChangeVisibleRows}
dataSource={this.state.dataSource}
renderRow={this.renderRow} />
)
}
}
const styles = {
body:{
flex:1,
},
rowItem:{
flex:1,
height:50,
flexDirection:'row',
justifyContent:'center',
alignItems:'center',
borderBottomWidth:1,
borderBottomColor:'#ddd',
},
rowTite:{
height:30,
alignItems:'center',
justifyContent:'center',
backgroundColor:'#ccc',
},
rowItemLeft:{
flex:1,
borderRightWidth:1,
borderRightColor:'#ccc',
},
rowItemRight:{
flex:3,
},
rowItemText:{
textAlign:'center'
},
}
export default List
課后練習
其他的API,自己可以試試
- initialListSize:一開始渲染幾個!如果寫成1的話,會看到一項一項出來。
- onChangeVisibleRows 的 visibleRows, changedRows: 前者是當前頁面可用看到的List Item 的ID 集合,以 { sectionID: { rowID: true }}形式表示,后者是頁面發生變化了,導致List Item變化的Item 狀態集合, { sectionID: { rowID: true | false }} 表示
- onEndReached / onEndReachedThreshold:設定了onEndReachedThreshold之后就判斷,快到底部onEndReachedThreshold像素的時候,調用onEndReachedThreshold。