React-native FlatList的基本用法

作者: 随遇而安_2750 | 来源:发表于2017-04-17 17:03 被阅读1953次
官网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轴,可以产生立体效果
  }
});


8.效果图如下:

效果图smartisanT2

相关文章

网友评论

  • lvbunny:可感谢楼主,为什么flatlist外面还要包裹一层scrollview?
  • 彼岸青园:写的很仔细,谢谢了
    2b35791598d5:@彼岸青园 不用在数据上加key,在FlatList加上属性keyExtractor={this._keyExtractor}
    _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"}}}]
    彼岸青园:按照你写的,每个ITEM都加了key了,还是报错,难受
  • asAnotherJack:flatlist外边为什么要再包裹一层scrollview呢?

本文标题:React-native FlatList的基本用法

本文链接:https://www.haomeiwen.com/subject/whitzttx.html