忽然發現本身的博客已經從原來的幾天更新一次變成了現在的一個月更新一次[捂臉],最近這一個月實在是太忙了,上個月月初的時候,接了一個RN的項目,作一個app,那時候老大問誰感興趣,我直接說我。其實本身對RN一直頗有興趣,可是那時候因爲在看Vue,因此並無去搞,如今恰好有個項目,正好我能夠去了解一下RN。說實話,這一答應沒關係,差點兒被RN氣死,之前以爲RN應該比較成熟了,通過這段時間作項目,發現RN的坑仍是不少的。react
在項目中我用到的比較多的是長列表,因此這篇文章主要是記一下對RN的ListView
和SectionList
的一些總結。我項目中使用的RN是0.44,關於爲何不用性能更好的FlatList
而使用老的ListView
,是由於本身自己第一次接觸RN,因此擔憂用很差FlatList
並且擔憂會有什麼bug,畢竟這個是在0.43版本才添加的。react-native
對於ListView
最重要的兩個屬性,一個是數據源(dataSource),再一個就是列表項渲染(renderRow)。ListView
能夠根據不一樣的數據結構對應的生成普通長列表和分組長列表。數組
普通長列表使用cloneWithRows(dataBlob, rowIdentities)
建立datasource,在項目中dataBlob
的數據結構以下:數據結構
[ {id:1}, {name:'Mark'}, ... ]
在使用renderRow(rowData, sectionID, rowID, highlightRow)
渲染列表項的時候,rowData
就是數組中每個對象。app
在項目中,遇到分組長列表,因爲RN版本爲0.44,因此有ListView
和SectionList
兩種選擇方案,最終我選擇了SectionList
,由於我發現ListView
的section
只能是一個簡單的字符串,不能是一個對象(這裏說實話我也不知道對不對,若不對,請指正並說明如何使用ListView
實現section
是一個對象)。異步
這裏我要吐槽一下RN的文檔,真的是有些地方寫的太簡單,好比在ListView
這裏寫到使用cloneWithRowsAndSections
的使用,只是簡單的說跟cloneWithRows
差很少,而接受的數據結構也就簡單的說明有三種:性能
{ sectionID_1: { rowID_1: <rowData1>, ... }, ... } //or { sectionID_1: [ <rowData1>, <rowData2>, ... ], ... } //or [ [ <rowData1>, <rowData2>, ... ], ... ]
可是具體這裏的是些什麼,我以爲沒有說清楚。因此我在項目中試了下用ListView
的cloneWithRowsAndSections
實現帶有粘性標題的列表,發現前兩種sectionID
只能是一個簡單的字符串或者數字,不能是一個對象,數據結構以下:優化
const dataSource1 = [ ['row1','row2'], ['row3','row4'], ['row5','row6'], ]; const dataSoure2 = { 'id1':['row1','row2'], 'id2':['row3','row4'], 'id3':['row5','row6'], } const dataSoure3 = { 'id1':{'row1','row2'}, 'id2':{'row3','row4'}, 'id3':{'row5','row6'}, } cloneWithRowsAndSections(dataSource);
dataSoure1生成的sectionHeader是數組的下標,而第二個第三個分別是對應的key
,在項目中個人sectionHeader是一個對象,相似於{headerName:'',headerContent:''}
,因此沒法使用。this
SectionList
和FlatList
同樣是新增的高性能長列表,在文檔中關於SectionList
接受的數據結構描述以下:spa
<SectionList renderItem={({item}) => <ListItem title={item.title} />} renderSectionHeader={({section}) => <H1 title={section.title} />} sections={[ // homogenous rendering between sections {data: [...], title: ...}, {data: [...], title: ...}, {data: [...], title: ...}, ]} /> <SectionList sections={[ // heterogeneous rendering between sections {data: [...], title: ..., renderItem: ...}, {data: [...], title: ..., renderItem: ...}, {data: [...], title: ..., renderItem: ...}, ]} />
說實話我第一次看到這個描述的時候很懵逼,這好像並沒說明data裏具體的數據結構是什麼樣子的,renderSectionHeader
中的數據又該如何取,在網上看了一個簡單的講解才大概知道sections
裏的數據應該怎麼寫,代碼以下:
import React , {Component} from 'react'; import { AppRegistry, StyleSheet, Text, View, SectionList } from 'react-native'; const dataSource = [ {data:[{name:'nader'},{name:'chris'}],key:'A'}, {data:[{name:'nick'},{name:'amanda'}],key:'B'} ]; export default class SectionListExample extends Component { renderItem = (item) => { return <Text style={styles.text}>{item.item.name}</Text> } renderHeader = (headerItem) => { return <Text style={styles.header}>{headerItem.section.key}</Text> } render(){ return( <View style={styles.container}> <SectionList renderItem={this.renderItem} renderSectionHeader={this.renderHeader} sections={dataSource} keyExtractor={(item)=>item.name} /> </View> ) } }
這裏須要注意一點就是renderItem
所用的數據key
必須是data
,並且key
必須是惟一的,而後其他的數據用在headerItem
中,這樣就很是容易在sectionHeader
中渲染出多個後臺給定的數據。
SectionList
和FlatList
須要注意幾點:ListView
。stickySectionHeadersEnabled={true}
的時候,粘性標題在往下滑動一下子再滑動回去的時候,標題會消失,這不知道是我代碼有問題仍是自己SectionList
的粘性標題在安卓下就有問題,不過在官方文檔中寫到Only enabled by default on iOS because that is the platform standard there.
因此多是SectionList
粘性標題在安卓下就有問題。SectionList
和FlatList
提供了一個叫legacyImplementation
的屬性,該屬性若是設置爲true
則使用舊的ListView
實現。在上述提到的兩個問題中,若是將SectionList
的legacyImplementation
設置爲true
,則兩個問題均解決。我的以爲這是官方提供的一個降級的辦法,因此其實咱們能夠拋棄ListView
轉而使用FlatList
和SectionList
,若是有什麼問題,讓它們用舊的ListView
實現。最後列幾個長列表(ListView
,SectionList
,FlatList
)的經常使用屬性
onEndReached
(function):當列表到達底部時候觸發的事件,關於這個事件須要注意一點,<span style='color:red'>當第一次渲染時,若是數據不足一屏(好比初始值是空的),這個事件也會被觸發,須要自行過濾</span>
onEndReachedThreshold
(number):距離最後一個列表元素多少像素時候觸發onEndReached
事件
initialListSize
(number):初始化時候渲染多少條數據,若是不寫擇時逐條渲染
showsVerticalScrollIndicator
(bool):默認狀況下,ListView有滾動條,當設置爲false的時候不顯示該滾動條(繼承自ScrollView)
pageSize
(number,僅ListView
有):每次事件循環(每幀)渲染的行數,經常使用於分頁,數據請求回來後渲染多少條,不設置則逐條渲染。