前端笔记6.FlatList列表处理

  1. 上次课程回顾

通过RN环境,配合View、Text、Image、TextInput、Button这些组件,可以实现简单的页面布局。

还可以通过StyleSheet控制显示的样式。

 

2、本次课程内容

2.1、FlatList的基本使用

FlatList类似Android中的ListView。

FlatList使用时,需要自定义每一行的内容,因此必须通过自己编写一个方法,来生成每一行的布局。

同时FlatList支持头部和尾部的自定义界面。

 

基本列表使用:

/**

 * Sample React Native App

 * https://github.com/facebook/react-native

 *

 * @format

 * @flow

 */

 

import React, {Component} from 'react';

import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native';

import logo from './images/logo.png';

 

 

var {height, width} = Dimensions.get('window');

 

const styles = StyleSheet.create({

  container : {

    flex:1,  // 填充满整个屏幕

    alignItems: 'center'

    // backgroundColor: "red"

  },

  mainLine : {

    width:width - 20,

    backgroundColor: "red",

    flexDirection: 'row'

  },

  lineId : {

    flex:1,

    fontSize: 30 ,

    backgroundColor: "blue"

  },

  lineTitle : {

    flex:2 ,

    fontSize: 25 ,

    backgroundColor: "yellow"

  }

});

 

 

//const mainUrl = "https://gank.io/api/data/Android/10/"

export default class App extends Component<Props> {

  constructor(props) {

    super(props);

    let arr = new Array();

    for (let i = 0;i < 20;i++) {

      arr[i] = {

        key:i + "",

        title:'测试数据' + i

      };

    }

 

    this.state = {

      data:arr

    }

  }

 

  _renderItem = ({item}) => {

    return (

      <View style={styles.mainLine}>

        <Text style={styles.lineId}>{item.key}</Text>

        <Text style={styles.lineTitle}>{item.title}</Text>

      </View>

    );

  }

 

 

  render() {

    return (

      <View style="styles.container">

          <FlatList

              data={this.state.data}

              renderItem={this._renderItem}

              >

          </FlatList>

      </View>

    );

  }

}

通过data属性设置要显示的数据,必须为数组类型,建议里面放入对象,对象中建议包含key属性,建议类型为 String。

还要通过renderItem方法来渲染每一行显示的格式,该属性建议自己编写一个方法来配合使用,方法中需要传入一个item参数,表示每一行的数据内容。

基于这个基本功能,我们可以加入一些扩展。

 

  1. 设置分割线

通过属性:ItemSeparatorComponent,来实现。

需要自定义一个方法,返回分割线的格式。

/**

 * Sample React Native App

 * https://github.com/facebook/react-native

 *

 * @format

 * @flow

 */

 

import React, {Component} from 'react';

import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native';

import logo from './images/logo.png';

 

 

var {height, width} = Dimensions.get('window');

 

const styles = StyleSheet.create({

  container : {

    flex:1,  // 填充满整个屏幕

    alignItems: 'center',

    // backgroundColor: "red"

  },

  mainLine : {

    width:width - 20,

    alignItems: "center",

      height: 40,

      lineHeight: 40,

    flexDirection: 'row'

  },

  lineId : {

    flex:1,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "blue"

  },

  lineTitle : {

    flex:2 ,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "yellow"

  }

});

 

 

//const mainUrl = "https://gank.io/api/data/Android/10/"

export default class App extends Component<Props> {

  constructor(props) {

    super(props);

    let arr = new Array();

    for (let i = 0;i < 20;i++) {

      arr[i] = {

        key:i + "",

        title:'测试数据' + i

      };

    }

 

    this.state = {

      data:arr

    }

  }

 

  _renderItem = ({item}) => {

    return (

      <View style={styles.mainLine}>

        <Text style={styles.lineId}>{item.key}</Text>

        <Text style={styles.lineTitle}>{item.title}</Text>

      </View>

    );

  }

 

  _seperator = () => {

    return (

      <View style={{width:width-20,height:2,backgroundColor:"green"}}/>

    );

  }

 

  render() {

    return (

      <View style="styles.container">

          <FlatList

              data={this.state.data}

              renderItem={this._renderItem}

              ItemSeparatorComponent={this._seperator}

              >

          </FlatList>

      </View>

    );

  }

}

 

  1. 下拉刷新

onRefresh和refreshing两个值配合可以完成下拉刷新。

/**

 * Sample React Native App

 * https://github.com/facebook/react-native

 *

 * @format

 * @flow

 */

 

import React, {Component} from 'react';

import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native';

import logo from './images/logo.png';

 

 

var {height, width} = Dimensions.get('window');

 

const styles = StyleSheet.create({

  container : {

    flex:1,  // 填充满整个屏幕

    alignItems: 'center',

    // backgroundColor: "red"

  },

  mainLine : {

    width:width - 20,

    alignItems: "center",

      height: 40,

      lineHeight: 40,

    flexDirection: 'row'

  },

  lineId : {

    flex:1,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "blue"

  },

  lineTitle : {

    flex:2 ,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "yellow"

  }

});

 

let arr = new Array();

for (let i = 0;i < 20;i++) {

  arr[i] = {

    key:i + "",

    title:'测试数据' + i

  };

}

 

//const mainUrl = "https://gank.io/api/data/Android/10/"

export default class App extends Component<Props> {

  constructor(props) {

    super(props);

 

 

    this.state = {

      data:arr ,

      isRefresh :false

    }

  }

 

  _renderItem = ({item}) => {

    return (

      <View style={styles.mainLine}>

        <Text style={styles.lineId}>{item.key}</Text>

        <Text style={styles.lineTitle}>{item.title}</Text>

      </View>

    );

  }

 

  _seperator = () => {

    return (

      <View style={{width:width-20,height:2,backgroundColor:"green"}}/>

    );

  }

 

  reloadData = () => {

    // 重新从网上查询数据,并替换到这里

    // 重新设置isRefresh为false

    let newArr = new Array();

    for (let i = 0;i < 20;i++) {

      newArr[i] = {

        key:1 + "",

        title:"新数据" + i

      }

    }

 

    // Alert.alert(arr[0].title);

    this.setState({

      data:newArr

    });

 

  }

 

  render() {

    return (

      <View style="styles.container">

          <FlatList

              data={this.state.data}

              renderItem={this._renderItem}

              onRefresh={this.reloadData}

              refreshing={this.state.isRefresh}

              ItemSeparatorComponent={this._seperator}

              >

          </FlatList>

      </View>

    );

  }

}

 

  1. 上拉加载更多

必须通过分页的功能来每次加载下一页的内容。

每次划动到最下面,都加载新的20条数据。

/**

 * Sample React Native App

 * https://github.com/facebook/react-native

 *

 * @format

 * @flow

 */

 

import React, {Component} from 'react';

import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native';

import logo from './images/logo.png';

 

 

var {height, width} = Dimensions.get('window');

 

const styles = StyleSheet.create({

  container : {

    flex:1,  // 填充满整个屏幕

    alignItems: 'center',

    // backgroundColor: "red"

  },

  mainLine : {

    width:width - 20,

    alignItems: "center",

      height: 40,

      lineHeight: 40,

    flexDirection: 'row'

  },

  lineId : {

    flex:1,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "blue"

  },

  lineTitle : {

    flex:2 ,

    fontSize: 25 ,

    height: 40,

    backgroundColor: "yellow"

  }

});

 

let arr = new Array();

for (let i = 0;i < 20;i++) {

  arr[i] = {

    key:i + "",

    title:'测试数据' + i

  };

}

 

//const mainUrl = "https://gank.io/api/data/Android/10/"

export default class App extends Component<Props> {

  constructor(props) {

    super(props);

    let allRows = 100;

    this.totalPage = Math.ceil(allRows / 20);

    this.state = {

      pageNo : 1,

      data:arr ,

      isRefresh :false

    }

  }

 

  _renderItem = ({item}) => {

    return (

      <View style={styles.mainLine}>

        <Text style={styles.lineId}>{item.key}</Text>

        <Text style={styles.lineTitle}>{item.title}</Text>

      </View>

    );

  }

 

  _seperator = () => {

    return (

      <View style={{width:width-20,height:2,backgroundColor:"green"}}/>

    );

  }

 

  reloadData = () => {

    // 重新从网上查询数据,并替换到这里

    // 重新设置isRefresh为false

    let newArr = new Array();

    for (let i = 0;i < 20;i++) {

      newArr[i] = {

        key:1 + "",

        title:"新数据" + i

      }

    }

 

    // Alert.alert(arr[0].title);

    this.setState({

      pageNo:1,

      data:newArr

    });

 

  }

 

  loadMoreData = () => {

    if (this.state.pageNo < this.totalPage) {

      this.state.pageNo ++ ;

      // 重新加载新的数据内容

      let newArr = new Array();

      for (let i = 0;i < 20;i++) {

        newArr[i] = {

          key : (i + (this.state.pageNo-1) * 20) + "",

          title : "更多数据" +  (i + (this.state.pageNo-1) * 20)

        }

      }

      // 将原有数据和新数据组合到一起

      let allData = this.state.data.concat(newArr);

      this.setState({

        pageNo : this.state.pageNo ,

        data:allData

      });

    }

  }

 

  _footerView = () => {

    if (this.state.pageNo < this.totalPage) {

      return (

        <View style={{width:width-20,alignItems: 'center'}}>

            <Text style={{fontSize: 30,color: "red"}}>正在加载更多...</Text>

        </View>

      );

    } else {

      return (

        <View style={{width:width-20,alignItems: 'center'}}>

            <Text style={{fontSize: 30,color: "green"}}>没有更多数据了</Text>

        </View>

      );

    }

  }

 

  render() {

    return (

      <View style="styles.container">

          <FlatList

              data={this.state.data}

              renderItem={this._renderItem}

              onRefresh={this.reloadData}

              refreshing={this.state.isRefresh}

              ListFooterComponent={this._footerView}

              onEndReached={this.loadMoreData}

              onEndReachedThreshold={1}

              ItemSeparatorComponent={this._seperator}

              >

          </FlatList>

      </View>

    );

  }

}

 

 

2.2、调用网络接口数据

这里使用一个现成的网络接口,返回JSON信息,实现分页列表显示数据的功能。

const mainUrl = https://gank.io/api/data/Android/10/ + pageNo

在ReactNative中,如果想调用网络数据接口,需要通过fetch方法来完成。

该方法传入以下参数:

url地址

一些参数信息,例如:method,headers,body

/**

 * Sample React Native App

 * https://github.com/facebook/react-native

 *

 * @format

 * @flow

 */

 

import React, {Component} from 'react';

import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native';

import logo from './images/logo.png';

 

 

var {height, width} = Dimensions.get('window');

 

const styles = StyleSheet.create({

  container : {

    flex:1,  // 填充满整个屏幕

    alignItems: 'center',

    // backgroundColor: "red"

  },

  mainLine : {

    width:width - 20,

    alignItems: "center",

    flexDirection: 'row'

  },

  lineId : {

    flex:1,

    fontSize: 25 ,

    backgroundColor: "blue"

  },

  lineTitle : {

    flex:2 ,

    fontSize: 25 ,

    backgroundColor: "yellow"

  }

});

 

let arr = new Array();

for (let i = 0;i < 20;i++) {

  arr[i] = {

    key:i + "",

    title:'测试数据' + i

  };

}

 

const mainUrl = "https://gank.io/api/data/Android/10/"

export default class App extends Component<Props> {

  constructor(props) {

    super(props);

    let allRows = 100;

    this.totalPage = Math.ceil(allRows / 10);

    this.state = {

      pageNo : 1,

      data:[] ,

      isRefresh :false

    };

    this.fetchData();

  }

 

  fetchData = () => {

    // 读取远程数据

    fetch(mainUrl + this.state.pageNo,{

      method:"GET"

    }).then((response) => response.json())

    .then((jsonObj) => {

      // 接收到结果后的处理

      // 循环结果,将结果内容放到data数组中

      let newArr =  new Array();

      for (let i = 0;i < jsonObj.results.length;i++) {

        let {_id,desc} = jsonObj.results[i];

        newArr[i] = {

          key : _id,

          title :  desc

        }

      }

      let allData = this.state.data.concat(newArr);

      this.setState({

        pageNo:this.state.pageNo ,

        data:allData

      });

    }).done() ;

  }

 

  _renderItem = ({item}) => {

    return (

      <View style={styles.mainLine}>

        <Text style={styles.lineId}>{item.key}</Text>

        <Text style={styles.lineTitle}>{item.title}</Text>

      </View>

    );

  }

 

  _seperator = () => {

    return (

      <View style={{width:width-20,height:2,backgroundColor:"green"}}/>

    );

  }

 

  reloadData = () => {

    // 重新从网上查询数据,并替换到这里

    // 重新设置isRefresh为false

 

    // Alert.alert(arr[0].title);

    this.setState({

      pageNo:1,

      data:[]

    });

    this.fetchData();

 

  }

 

  loadMoreData = () => {

    if (this.state.pageNo < this.totalPage) {

      this.state.pageNo ++ ;

      this.fetchData();

    }

  }

 

  _footerView = () => {

    if (this.state.pageNo < this.totalPage) {

      return (

        <View style={{width:width-20,alignItems: 'center'}}>

            <Text style={{fontSize: 30,color: "red"}}>正在加载更多...</Text>

        </View>

      );

    } else {

      return (

        <View style={{width:width-20,alignItems: 'center'}}>

            <Text style={{fontSize: 30,color: "green"}}>没有更多数据了</Text>

        </View>

      );

    }

  }

 

  render() {

    return (

      <View style="styles.container">

          <FlatList

              data={this.state.data}

              renderItem={this._renderItem}

              onRefresh={this.reloadData}

              refreshing={this.state.isRefresh}

              ListFooterComponent={this._footerView}

              onEndReached={this.loadMoreData}

              onEndReachedThreshold={1}

              ItemSeparatorComponent={this._seperator}

              >

          </FlatList>

      </View>

    );

  }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值