今天小萌说一下一个在项目中最常用的组件FaltList,这个类似于iOS中的tableView,Android中的ListView,这个组件做了足够的优化,ListView处理数据较多的时候卡顿特别明显,测试也很简单,一个数组,循环200次,放在ListView上,卡顿特别明显,因此小萌改用FaltList啦。
FlaltList支持以下常用的功能
- 完全跨平台。
- 支持水平布局模式。
- 行组件显示或隐藏时可配置回调事件。
- 支持单独的头部组件。
- 支持单独的尾部组件。
- 支持自定义行间分隔线。
- 支持下拉刷新。
- 支持上拉加载。
- 支持跳转到指定行(ScrollToIndex)。
如果需要悬浮分组使用SectionList组件,但是没有可以控制SectionList这个组件是否需要悬浮的属性,但是我们不一定需要悬浮,所以我们还是常用FlaltList组件。
最简单使用data和renderItem
最简单只要给FlatList的两个props指定值就可以了,一个是data,一个是renderItem。数据源一般就是一个数组,而renderItem就是每一行的绘制方法。绘制行的时候只需要获取当前的数据项就可以,不过这个时候会报警告的,不过现在不用在意,下面会有说明的哦。
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
关键keyExtractor
这个可是去除上面报的警告的关键之处,普通的写法也一定会报警告的,下面说一种不会报警告的,一定要写这个keyExtractor,要不然太多的警告看着不舒服。
如果给的数据json数据
var dataArray1 = [{titleId:"23", title:"扫一扫"}];
就如下面所写
keyExtractor={item => item.titleId}
如果是自己定义的数组如是这样的为了处理警告:
var dataArray2 = [{title:"省流量模式"},{title:"消息提醒"},
{title:"邀请好友"},{title:"清空缓存"}];
keyExtractor={(item, index) => index.toString()}
这样写就可以处理掉警告啦。。。。。。
这个 item.titleId可是很主要的,初学者特别容易出现这个错误,一出现警告就去查资料,这个很浪费时间,耐心看下去才是。
分割线ItemSeperatorComponent
我们的APP本身在显示message的时候没有明显的分割线,而是用一块一块的方式显示的。如果只是简单的一条线分割两行,那么只需要设置行组件的boderBottom相关的属性就可以了,这样每个行组件的下面都有一条线,在项目中需要根据需求来灵活应用。
如设置行组件的borderBottom:
<View style={ borderBottomWidth: 0.5, borderBottomColor: 'grey' }>
</View>
如果你一定要一个分割线的话可以使用FlatList的ItemSeperatorComponent prop。如:
renderSeparator = () => {
return <View style={{height:1,backgroundColor:'gray'}}/>;
}
调用方法
<FlatList
...
ItemSeparatorComponent={this.renderSeparator}
/>
在FlatList里使用prop ItemSeparatorComponent就可以。
注意:FlatList的顶部和底部的分割组件是不绘制的。
ListHeaderComponent和ListFooterComponent
这个和上面的ItemSeperatorComponent的用法是一样的,直接上代码
renderHeader = () => {
return <Text style={[styles.txt,{backgroundColor:'red'}]}>这是头部</Text>;
}
renderFooter = () => {
return <Text style={[styles.txt,{backgroundColor:'black'}]}>这是尾部</Text>;
}
用法:
<FlatList
...
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
/>
getItemLayout
getItemLayout是一种可选的优化方式,如果您事先知道的高度,就可以跳过对动态内容的测量。getItemLayout是最高效的,并且如果您有固定高度的物品,则易于使用,例如:
getItemLayout={(data,index)=>(
{length: ITEM_HEIGHT, offset: (ITEM_HEIGHT+2) * index, index}
)}
getItemLayout对于数百个项目的列表,添加可以是一个很好的性能提升。如果指定,请记住在偏移量计算中包含分隔符长度(高度或宽度)ItemSeparatorComponent,比如上面的意思就是分割线的高度为2。
下拉刷新和上拉加载更多
自从这两个交互的方式自从发明出来之后就基本上是每一个应用里list的标配了。我们来看看FlatList如何添加这两个功能的。
render() {
return (
<View style={styles.container}>
<FlatList
...
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0} />
</View>
);
}
FlatList的几个props:
refreshing:表明list是否在refresh的状态。
onRefresh:开始refresh的事件。在这个方法里开始设置refresh的时候组件的state,并在setState方法的回调里开始请求后端的数据。
onEndReached: 上拉加载跟个多的事件。在这里设置加载更多对应的组件状态,并在setState方法的回调里请求后端数据。
onEndReachedThreshold:这个值是触发onEndReached方法的阈值。值是RN的逻辑像素。
下面看一下下拉刷新的方法。上拉加载更多基本类似,各位可以参考代码。
//刷新注意状态变化
handleRefresh = () => {
this.setState({
refreshing: true,
data: [],
}, () => {
this.requestData();
});
}
请求github的API的方法是:
requestData = () => {
const url = '';
fetch(url).then(res => {
console.log('started fetch');
return res.json()
}).then(res => {
this.setState({
data: [...this.state.data, ...res], //这里如果不太清楚补充JavaScript 数组知识
refreshing: false,
});
}).catch(err => {
console.log('==> fetch error', err);
this.setState({ refreshing: false});
});
}
在下拉刷新开始请求后端的数据的时候首先设置组件状态。给组件的state设置初始值。
下拉刷新的话,每次都会清空已经存在的数据,所以data[]初始化一下,接下来要开始刷新,那么表示刷新的小菊花就需要转起来,所以refreshing的值设为true。
在setState方法的回调里开始请求后端的数据。数据返回之后,下拉刷新或者加载更多的状态都不存在。如果请求数据的时候有错,那么我们要处理错误。所以秦秋网络数据的方法为:
requestData = () => {
const url = '';
fetch(url).then(res => {
console.log('started fetch');
return res.json()
}).then(res => {
this.setState({
data: [...this.state.data, ...res],
refreshing: false,
});
}).catch(err => {
console.log('==> fetch error', err);
this.setState({ refreshing: false});
});
}
在返回的数据转化为json格式之后,合成data。这个时候refreshing已经完成值设置为false。数据是累加的:data: [...this.state.data, ...res],,所以每次在下拉刷新的时候this.setState({data: []}),在上拉加载更多的时候可以留着data不置空。
horizontal numColumns columnWrapperStyle
horizontal:这个属性是决定Falist是竖排或者横排,如果为true是横排,false是竖排,默认为false竖排。
numColumns:多少列
columnWrapperStyle:如果设置了多列布局(即将numColumns
值设为大于1的整数),则可以额外指定此样式作用在每行容器上。
render() {
return (
<View style={styles.container}>
<FlatList
...
horizontal={true}
numColumns ={2}
columnWrapperStyle={{borderWidth:2,borderColor:'black',paddingLeft:100}}
renderItem = {this.renderRow}
/>
</View>
);
}
方法
scrollToEnd
滚动到底部。如果设置不getItemLayout
属性的话教育,可能会比较卡。
scrollToIndex
将位于指定位置的元素滚动到可视区的指定位置,当viewPosition
它为0时将它滚动到屏幕顶部,为1时将它滚动到屏幕底部,为0.5时将它滚动到屏幕中央。
如果设置不getItemLayout
属性的话教育,无法跳转到当前可视区域以外的位置。
scrollToOffset
滚动列表到指定的偏移(以像素为单位),于等同ScrollView
的scrollTo
方法。
<Button title='滚动到指定位置' onPress={()=>{
//this._flatList.scrollToEnd();
//this._flatList.scrollToIndex({viewPosition:0,index:8});
this._flatList.scrollToOffset({animated: true, offset: 2000});
}}/>
网友评论