官网FlatList解读
FlatList被称为升级版的ListView,在大量数据渲染的时候,不会造成内存飙升,进而具有很好的性能体验,目前还在试水阶段,网络上没有多少“最佳实践”,RN开发是一个不断挖坑填坑的旅途,在这一片泥泞的路上,希望通过一点总结和尝试会变成一块块垫脚石,给这条路添加一点点平坦,为跨平台生态圈增加些许色彩!
1.引入FlatList组件
import {
AppRegistry,
StyleSheet,
Text,
View
ActivityIndicator,
FlatList,
ScrollView
} from 'react-native';
2.模拟网络数据
const REQUEST_URL = 'https://api.github.com/search/repositories?q=ALL&sort=stars';
3.设置状态机state
constructor(props){
super(props);
this.state = {
isLoading: true,
//网络请求状态
error: false,
errorInfo: "",
dataArray: [],
}
}
4.请求网络数据方法
_fetchData(){
fetch(REQUEST_URL)
.then((response) => response.json())
.then((data) => {
let datalist = data.items;
let dataBlog = [];
let i = 0;
datalist.map((item) => {
dataBlog.push({
key:i,
value:item
})
i++;
})
this.setState({
dataArray:dataBlog,
isLoading:false,
})
datalist = null;
dataBlog = null;
})
.catch((err) => {
this.setState({
error:true,
errorInfo:err
})
})
.done()
}
注意:
如果将dataArray直接设置为data.items,运行时会报错:VirtualizedList: missing keys for items, make sure to specify a key property on each item or provide a custom keyExtractor.
因此,要将dataArray设置为dataBlog的格式。
5.渲染每一个item的方法
_renderItemView(item){
console.log(item.index)
// VirtualizedList: missing keys for items,
// make sure to specify a key property on each item or provide a custom keyExtractor.
// item数据结构中必须要有个key
return (
<View style={styles.cellStyle}>
<Text>{item.item.value.description}</Text>
</View>
)
}
注意:要想拿到数组中的数据,必须指定item.item.value,不信可以打印出item试试,观察他的数据结构。
6.数据没有加载出来的时候(菊花图)
renderLoadingView(){
return (
<View style={styles.container}>
<ActivityIndicator
animating={true}
style={{height: 80}}
color='red'
size="large"
/>
</View>
)
}
6.加载失败的时候
//加载失败view
renderErrorView(error) {
return (
<View style={styles.container}>
<Text>
Fail: {error}
</Text>
</View>
);
}
7.完整的代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
TouchableHighlight,
TouchableOpacity,
ActivityIndicator,
FlatList,
ScrollView,
RefreshControl
} from 'react-native';
// 顶部标题View
import NavigationBar from '../common/NavigationBar';
const REQUEST_URL = 'https://api.github.com/search/repositories?q=ALL&sort=stars';
export default class MusicPage extends Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
//网络请求状态
error: false,
errorInfo: "",
dataArray: [],
}
}
componentDidMount() {
this._fetchData();
}
_fetchData(){
fetch(REQUEST_URL)
.then((response) => response.json())
.then((data) => {
let datalist = data.items;
let dataBlog = [];
let i = 0;
datalist.map((item) => {
dataBlog.push({
key:i,
value:item
})
i++;
})
this.setState({
dataArray:dataBlog,
isLoading:false,
})
datalist = null;
dataBlog = null;
})
.catch((err) => {
this.setState({
error:true,
errorInfo:err
})
})
.done()
}
_renderItemView(item){
console.log(item.index)
// VirtualizedList: missing keys for items,
// make sure to specify a key property on each item or provide a custom keyExtractor.
// item数据结构中必须要有个key
return (
<View style={styles.cellStyle}>
<Text>{item.item.value.description}</Text>
</View>
)
}
renderLoadingView(){
return (
<View style={styles.container}>
<ActivityIndicator
animating={true}
style={{height: 80}}
color='red'
size="large"
/>
</View>
)
}
//加载失败view
renderErrorView(error) {
return (
<View style={styles.container}>
<Text>
Fail: {error}
</Text>
</View>
);
}
_renderFlatlist(){
//第一次加载等待的view
if (this.state.isLoading && !this.state.error) {
return this.renderLoadingView();
} else if (this.state.error) {
//请求失败view
return this.renderErrorView(this.state.errorInfo);
}
return (
<ScrollView>
<FlatList
data={this.state.dataArray}
renderItem={(item)=>this._renderItemView(item)}
/>
</ScrollView>
)
}
render() {
return (
<View style={styles.container}>
<NavigationBar
title='FlatList'
/>
{/* 这里渲染选项卡UI */}
{this._renderFlatlist()}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
cellStyle:{
flex: 1,
backgroundColor: 'white',
padding: 10,
paddingVertical:20,
marginLeft: 5,
marginRight: 5,
marginVertical: 3,
borderColor: '#dddddd',
borderStyle: null,
borderWidth: 0.5,
borderRadius: 2,
shadowColor: 'gray', // 设置阴影
shadowOffset: {width:0.5, height: 0.5},
shadowOpacity: 0.4, // 透明度
shadowRadius: 1,
elevation:2 // 高度,设置Z轴,可以产生立体效果
}
});
网友评论
_keyExtractor = (item, index) => item.id; id替换成你数据里面的任何key值
[{"key":0,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-06 22:00","hum":"24","pop":"0","pres":"1024","tmp":"-1","wind":{"deg":"278","dir":"西风","sc":"微风","spd":"6"}}},{"key":1,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 01:00","hum":"32","pop":"0","pres":"1027","tmp":"-2","wind":{"deg":"325","dir":"西北风","sc":"微风","spd":"8"}}},{"key":2,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 04:00","hum":"33","pop":"0","pres":"1027","tmp":"-2","wind":{"deg":"331","dir":"西北风","sc":"微风","spd":"9"}}},{"key":3,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 07:00","hum":"32","pop":"0","pres":"1029","tmp":"-1","wind":{"deg":"333","dir":"西北风","sc":"微风","spd":"9"}}},{"key":4,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 10:00","hum":"25","pop":"0","pres":"1030","tmp":"2","wind":{"deg":"327","dir":"西北风","sc":"微风","spd":"15"}}},{"key":5,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 13:00","hum":"20","pop":"0","pres":"1029","tmp":"4","wind":{"deg":"320","dir":"西北风","sc":"3-4","spd":"18"}}},{"key":6,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 16:00","hum":"21","pop":"0","pres":"1029","tmp":"3","wind":{"deg":"325","dir":"西北风","sc":"3-4","spd":"19"}}},{"key":7,"value":{"cond":{"code":"103","txt":"晴间多云"},"date":"2017-12-07 19:00","hum":"25","pop":"0","pres":"1031","tmp":"1","wind":{"deg":"318","dir":"西北风","sc":"微风","spd":"11"}}}]