ReactNative之FlatList的具體使用方法,reactnative
之前使用的組件是ListView,當時要添加一個下拉重新整理,上拉載入的功能,所以對ListView做了一些封裝,但是後來看官方文檔,不建議再使用ListView,因為效率問題,做過Android的朋友都知道,Android的ListView如果不自己處理一下,也是有效率問題的。所以官方又推出了FlatList,而且內建上拉下拉的功能。
功能簡介
- 完全跨平台。
- 支援水平配置模式。
- 行組件顯示或隱藏時可配置回調事件。
- 支援單獨的頭部組件。
- 支援單獨的尾部組件。
- 支援自訂行間分隔線。
- 支援下拉重新整理。
- 支援上拉載入。
- 支援跳轉到指定行(ScrollToIndex)。
如果需要分組/類/區(section),請使用SectionList(這個我們會在之後的文章中介紹)
使用
FlatList如果只做簡單使用也是很簡單的,這裡我們會分難以程度,逐漸介紹:
直接使用
<FlatListdata={[{key: 'a'}, {key: 'b'}]}renderItem={({item}) => <Text>{item.key}</Text>}/>
可以看出跟之前的ListView很像,但是其中少了dataSource,這裡,我們只需要傳遞資料,其它的都交給FlatList處理好了。
屬性說明
- ItemSeparatorComponent行與行之間的分隔線組件。不會出現在第一行之前和最後一行之後。在這裡可以根據需要插入一個view
- ListEmptyComponent列表為空白時渲染該組件。可以是React Component, 也可以是一個render函數, 或者渲染好的element。
- ListFooterComponent尾部組件
- ListHeaderComponent頭部組件
- columnWrapperStyle如果設定了多欄版面配置(即將numColumns值設為大於1的整數),則可以額外指定此樣式作用在每行容器上。
- data為了簡化起見,data屬性目前只支援普通數組。如果需要使用其他特殊資料結構,例如immutable數組,請直接使用更底層的VirtualizedList組件。
- extraData如果有除data以外的資料用在列表中(不論是用在renderItem還是Header或者Footer中),請在此屬性中指定。同時此資料在修改時也需要先修改其引用地址(比如先複製到一個新的Object或者數組中),然後再修改其值,否則介面很可能不會重新整理。
- getItem擷取每個Item
- getItemCount擷取Item屬相
- getItemLayout是一個可選的最佳化,用於避免動態測量內容尺寸的開銷,不過前提是你可以提前知道內容的高度。如果你的行高是固定的getItemLayout用起來就既高效又簡單,類似下面這樣:getItemLayout={(data, index) => ( {length: 行高, offset: 行高 * index, index} )}注意如果你指定了SeparatorComponent,請把分隔線的尺寸也考慮到offset的計算之中。
- horizontal設定為true則變為水平配置模式。
- initialNumToRender指定一開始渲染的元素數量,最好剛剛夠填滿一個螢幕,這樣保證了用最短的時間給使用者呈現可見的內容。注意這第一批次渲染的元素不會在滑動過程中被卸載,這樣是為了保證使用者執行返回頂部的操作時,不需要重新渲染首批元素。
- initialScrollIndex指定渲染開始的item index
- keyExtractor此函數用於為給定的item產生一個不重複的key。Key的作用是使React能夠區分同類元素的不同個體,以便在重新整理時能夠確定其變化的位置,減少重新渲染的開銷。若不指定此函數,則預設抽取item.key作為key值。若item.key也不存在,則使用數組下標。
- legacyImplementation設定為true則使用舊的ListView的實現。
- numColumns多欄版面配置只能在非水平模式下使用,即必須是horizontal={false}。此時組件內元素會從左至右從上到下按Z字形排列,類似啟用了flexWrap的布局。組件內元素必須是等高的——暫時還無法支援瀑布流布局。
- onEndReached當列表被滾動到距離內容最底部不足onEndReachedThreshold的距離時調用。
- onEndReachedThreshold決定當距離內容最底部還有多遠時觸發onEndReached回調。注意此參數是一個比值而非像素單位。比如,0.5表示距離內容最底部的距離為當前列表可見長度的一半時觸發。
- onRefresh如果設定了此選項,則會在列表頭部添加一個標準的RefreshControl控制項,以便實現“下拉重新整理”的功能。同時你需要正確設定refreshing屬性。
- onViewableItemsChanged在可見行元素變化時調用。可見範圍和變化頻率等參數的配置請設定viewabilityconfig屬性
- refreshing在等待載入新資料時將此屬性設為true,列表就會顯示出一個正在載入的符號。
- renderItem根據行資料data,渲染每一行的組件。這個參照下面的demo
- viewabilityConfig請參考ViewabilityHelper 的源碼來瞭解具體的配置。
方法
scrollToEnd
滾動到底部。如果不設定getItemLayout
屬性的話,可能會比較卡。
scrollToIndex
滾動到指定index的item
如果不設定getItemLayout
屬性的話,無法跳轉到當前可視地區以外的位置。
scrollToItem
滾動到指定item,如果不設定getItemLayout
屬性的話,可能會比較卡。
scrollToOffset
滾動指定距離
Demo:
import React, {Component} from 'react';import { StyleSheet, View, FlatList, Text, Button,} from 'react-native';var ITEM_HEIGHT = 100;export default class FlatListDemo extends Component { _flatList; _renderItem = (item) => { var txt = '第' + item.index + '個' + ' title=' + item.item.title; var bgColor = item.index % 2 == 0 ? 'red' : 'blue'; return <Text style={[{flex:1,height:ITEM_HEIGHT,backgroundColor:bgColor},styles.txt]}>{txt}</Text> } _header = () => { return <Text style={[styles.txt,{backgroundColor:'black'}]}>這是頭部</Text>; } _footer = () => { return <Text style={[styles.txt,{backgroundColor:'black'}]}>這是尾部</Text>; } _separator = () => { return <View style={{height:2,backgroundColor:'yellow'}}/>; } render() { var data = []; for (var i = 0; i < 100; i++) { data.push({key: i, title: i + ''}); } return ( <View style={{flex:1}}> <Button title='滾動到指定位置' onPress={()=>{ //this._flatList.scrollToEnd(); //this._flatList.scrollToIndex({viewPosition:0,index:8}); this._flatList.scrollToOffset({animated: true, offset: 2000}); }}/> <View style={{flex:1}}> <FlatList ref={(flatList)=>this._flatList = flatList} ListHeaderComponent={this._header} ListFooterComponent={this._footer} ItemSeparatorComponent={this._separator} renderItem={this._renderItem} //numColumns ={3} //columnWrapperStyle={{borderWidth:2,borderColor:'black',paddingLeft:20}} //horizontal={true} //getItemLayout={(data,index)=>( //{length: ITEM_HEIGHT, offset: (ITEM_HEIGHT+2) * index, index} //)} //onEndReachedThreshold={5} //onEndReached={(info)=>{ //console.warn(info.distanceFromEnd); //}} //onViewableItemsChanged={(info)=>{ //console.warn(info); //}} data={data}> </FlatList> </View> </View> ); }}const styles = StyleSheet.create({ txt: { textAlign: 'center', textAlignVertical: 'center', color: 'white', fontSize: 30, }});
:
進階使用
在這裡我準備了一份程式碼範例:
const {width,height}=Dimensions.get('window')export default class Main extends Component{ // 構造 constructor(props) { super(props); } refreshing(){ let timer = setTimeout(()=>{ clearTimeout(timer) alert('重新整理成功') },1500) } _onload(){ let timer = setTimeout(()=>{ clearTimeout(timer) alert('載入成功') },1500) } render() { var data = []; for (var i = 0; i < 100; i++) { data.push({key: i, title: i + ''}); } return ( <View style={{flex:1}}> <Button title='滾動到指定位置' onPress={()=>{ this._flatList.scrollToOffset({animated: true, offset: 2000}); }}/> <View style={{flex:1}}> <FlatList ref={(flatList)=>this._flatList = flatList} ListHeaderComponent={this._header} ListFooterComponent={this._footer} ItemSeparatorComponent={this._separator} renderItem={this._renderItem} onRefresh={this.refreshing} refreshing={false} onEndReachedThreshold={0} onEndReached={ this._onload } numColumns ={3} columnWrapperStyle={{borderWidth:2,borderColor:'black',paddingLeft:20}} //horizontal={true} getItemLayout={(data,index)=>( {length: 100, offset: (100+2) * index, index} )} data={data}> </FlatList> </View> </View> ); } _renderItem = (item) => { var txt = '第' + item.index + '個' + ' title=' + item.item.title; var bgColor = item.index % 2 == 0 ? 'red' : 'blue'; return <Text style={[{flex:1,height:100,backgroundColor:bgColor},styles.txt]}>{txt}</Text> } _header = () => { return <Text style={[styles.txt,{backgroundColor:'black'}]}>這是頭部</Text>; } _footer = () => { return <Text style={[styles.txt,{backgroundColor:'black'}]}>這是尾部</Text>; } _separator = () => { return <View style={{height:2,backgroundColor:'yellow'}}/>; }}const styles=StyleSheet.create({ container:{ }, content:{ width:width, height:height, backgroundColor:'yellow', justifyContent:'center', alignItems:'center' }, cell:{ height:100, backgroundColor:'purple', alignItems:'center', justifyContent:'center', borderBottomColor:'#ececec', borderBottomWidth:1 }, txt: { textAlign: 'center', textAlignVertical: 'center', color: 'white', fontSize: 30, }})
運行效果如下:
總結
總體來說Flatlist還是比ListView用起來方便的,而且提供的功能更多。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。