React-Native开发大全React-Native日记

React-native FlatList的基本用法

2017-04-17  本文已影响1953人  随遇而安_2750
官网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
上一篇下一篇

猜你喜欢

热点阅读