ReactNative之FlatList的具體使用方法
之前使用的組件是ListView,當時要添加一個下拉刷新,上拉加載的功能,所以對ListView做了一些封裝,但是后來看官方文檔,不建議再使用ListView,因為效率問題,做過Android的朋友都知道,Android的ListView如果不自己處理一下,也是有效率問題的。所以官方又推出了FlatList,而且自帶上拉下拉的功能。
功能簡介
- 完全跨平臺。
- 支持水平布局模式。
- 行組件顯示或隱藏時可配置回調(diào)事件。
- 支持單獨的頭部組件。
- 支持單獨的尾部組件。
- 支持自定義行間分隔線。
- 支持下拉刷新。
- 支持上拉加載。
- 支持跳轉(zhuǎn)到指定行(ScrollToIndex)。
如果需要分組/類/區(qū)(section),請使用SectionList(這個我們會在之后的文章中介紹)
使用
FlatList如果只做簡單使用也是很簡單的,這里我們會分難以程度,逐漸介紹:
直接使用
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
可以看出跟之前的ListView很像,但是其中少了dataSource,這里,我們只需要傳遞數(shù)據(jù),其它的都交給FlatList處理好了。
屬性說明
- ItemSeparatorComponent行與行之間的分隔線組件。不會出現(xiàn)在第一行之前和最后一行之后。在這里可以根據(jù)需要插入一個view
- ListEmptyComponent列表為空時渲染該組件??梢允荝eact Component, 也可以是一個render函數(shù), 或者渲染好的element。
- ListFooterComponent尾部組件
- ListHeaderComponent頭部組件
- columnWrapperStyle如果設置了多列布局(即將numColumns值設為大于1的整數(shù)),則可以額外指定此樣式作用在每行容器上。
- data為了簡化起見,data屬性目前只支持普通數(shù)組。如果需要使用其他特殊數(shù)據(jù)結構,例如immutable數(shù)組,請直接使用更底層的VirtualizedList組件。
- extraData如果有除data以外的數(shù)據(jù)用在列表中(不論是用在renderItem還是Header或者Footer中),請在此屬性中指定。同時此數(shù)據(jù)在修改時也需要先修改其引用地址(比如先復制到一個新的Object或者數(shù)組中),然后再修改其值,否則界面很可能不會刷新。
- getItem獲取每個Item
- getItemCount獲取Item屬相
- getItemLayout是一個可選的優(yōu)化,用于避免動態(tài)測量內(nèi)容尺寸的開銷,不過前提是你可以提前知道內(nèi)容的高度。如果你的行高是固定的getItemLayout用起來就既高效又簡單,類似下面這樣:getItemLayout={(data, index) => ( {length: 行高, offset: 行高 * index, index} )}注意如果你指定了SeparatorComponent,請把分隔線的尺寸也考慮到offset的計算之中。
- horizontal設置為true則變?yōu)樗讲季帜J健?/li>
- initialNumToRender指定一開始渲染的元素數(shù)量,最好剛剛夠填滿一個屏幕,這樣保證了用最短的時間給用戶呈現(xiàn)可見的內(nèi)容。注意這第一批次渲染的元素不會在滑動過程中被卸載,這樣是為了保證用戶執(zhí)行返回頂部的操作時,不需要重新渲染首批元素。
- initialScrollIndex指定渲染開始的item index
- keyExtractor此函數(shù)用于為給定的item生成一個不重復的key。Key的作用是使React能夠區(qū)分同類元素的不同個體,以便在刷新時能夠確定其變化的位置,減少重新渲染的開銷。若不指定此函數(shù),則默認抽取item.key作為key值。若item.key也不存在,則使用數(shù)組下標。
- legacyImplementation設置為true則使用舊的ListView的實現(xiàn)。
- numColumns多列布局只能在非水平模式下使用,即必須是horizontal={false}。此時組件內(nèi)元素會從左到右從上到下按Z字形排列,類似啟用了flexWrap的布局。組件內(nèi)元素必須是等高的——暫時還無法支持瀑布流布局。
- onEndReached當列表被滾動到距離內(nèi)容最底部不足onEndReachedThreshold的距離時調(diào)用。
- onEndReachedThreshold決定當距離內(nèi)容最底部還有多遠時觸發(fā)onEndReached回調(diào)。注意此參數(shù)是一個比值而非像素單位。比如,0.5表示距離內(nèi)容最底部的距離為當前列表可見長度的一半時觸發(fā)。
- onRefresh如果設置了此選項,則會在列表頭部添加一個標準的RefreshControl控件,以便實現(xiàn)“下拉刷新”的功能。同時你需要正確設置refreshing屬性。
- onViewableItemsChanged在可見行元素變化時調(diào)用??梢姺秶妥兓l率等參數(shù)的配置請設置viewabilityconfig屬性
- refreshing在等待加載新數(shù)據(jù)時將此屬性設為true,列表就會顯示出一個正在加載的符號。
- renderItem根據(jù)行數(shù)據(jù)data,渲染每一行的組件。這個參照下面的demo
- viewabilityConfig請參考ViewabilityHelper 的源碼來了解具體的配置。
方法
scrollToEnd
滾動到底部。如果不設置getItemLayout
屬性的話,可能會比較卡。
scrollToIndex
滾動到指定index的item
如果不設置getItemLayout
屬性的話,無法跳轉(zhuǎn)到當前可視區(qū)域以外的位置。
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用起來方便的,而且提供的功能更多。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
React Native 集成 ArcGIS 地圖的詳細過程
ArcGIS官方提供了 JavaScript SDK,也提供了 ArcGIS-Runtime-SDK-iOS,但是并沒有提供 React Native的版本,所以這里使用了 react-native-arcgis-mapview 庫,本文給大家介紹React Native 集成 ArcGIS 地圖的詳細過程,感興趣的朋友跟隨小編一起看看吧2024-06-06
React Native使用Modal自定義分享界面的示例代碼
本篇文章主要介紹了React Native使用Modal自定義分享界面的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
關于React Native使用axios進行網(wǎng)絡請求的方法
axios是一個基于Promise的Http網(wǎng)絡庫,可運行在瀏覽器端和Node.js中,Vue應用的網(wǎng)絡請求基本都是使用它完成的。這篇文章主要介紹了React Native使用axios進行網(wǎng)絡請求,需要的朋友可以參考下2021-08-08
Redux DevTools不能顯示數(shù)據(jù)問題
這篇文章主要介紹了Redux DevTools不能顯示數(shù)據(jù)問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
React Native AsyncStorage本地存儲工具類
這篇文章主要為大家分享了React Native AsyncStorage本地存儲工具類,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10

