React Native 中的 FlatList

作者: FatBro_师兄 | 来源:发表于2019-08-14 21:34 被阅读19次

前言

嗯...

怎么说呢,我换公司了,做为一个比较被动的人,这次入职后,发现要使用React Native开发APP了,有的紧张有点慌。

既来之则安之吧!

自己首先在React Native中文官网,将入门的东西都看了一遍,然后又吧React.js 学习了一下,虽然以前有点 js 方面的基础,但也好久没有使用了,重头开始吧!

之后的一个月,我一边学习,一边熟悉项目,中间有段时间不知道从何着手,在网上找各种教程,看的比较艰难!

而开始熟悉项目的时候,搭建环境,跑项目,都让我狠狠的拽了一把头发,如果大家有问题,还是可以和我探讨探讨的,毕竟遇到了很多问题,也解决了很多问题!

好吧,步入正题吧,这次要写的是React Native 中的 FlatList 控件,因为在项目中有用到,但是用的不熟悉,所以加深下印象!

FlatList

在使用 FlatList 的时候,首先看的是 官网API,但是很多文字性的描述是看不见什么东西的,然后我就结合其他前辈的教程,自己摸索了一下,不对之处请见谅!

首先,我新建一个 FlatList.js 文件来写这个Demo
在开始,我们要导入一些资源:

import React, { Component } from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

//屏幕信息
const dimensions = require('Dimensions');
//获取屏幕的宽度和高度
const { width, height } = dimensions.get('window');

前两个import是必须要引入的,后两个则是根据页面需求加入。

然后,我们开始定义一个外部可以使用的Component

export default class FlatListPage extends Component

这样,我们在 index.js 中,就可以将此页面设为首页:

import FlatListPage from './FlatListPage'

AppRegistry.registerComponent(appName, () => FlatListPage);

之后,我们开始在constructor中定义我们需要用到的属性:

 constructor(props) {
        super(props)
        this.page = 0;
        this.state = {
            data: [],
            isRefresh: false,
            isCloseLoadMore: false,//当数据加载完后,设为true,不在加载更多
            isLoadingMore:false //是否在加载更多
        }   

    }

现在,我们可以在render()中展示我们的FlatList组件了:

 render() {
        return (
            <FlatList style={styles.flatListContainer}
                data={this.state.data}
                //item布局
                renderItem={({ item }) => this._item(item)}
                //下拉刷新
                onRefresh={() => this._refresh()}
                refreshing={this.state.isRefresh}
                //加载更多
                onEndReached={() => this._loadMore()}
                onEndReachedThreshold={0.1}
                //没数据时候的布局
                ListEmptyComponent={this._emptyView}
                //头布局
                ListHeaderComponent={this._headerView}
                //尾布局
                ListFooterComponent={this._footerView}
            />
        )
    }

可以看到,我将下拉刷新、上拉加载、空页面、头布局、尾布局都写了,这些是我们常用到的一些功能,当然,我也暂时就了解到这里。
其中 renderItem 相当于 Androidlistviewitem 布局:

 _item(item) {
        console.log("_item--id=" + item.id)
        return (
            <View style={styles.itemContainer} key={item.id}>
                <Text style={styles.text}> {item.title}</Text>
                <View style={styles.itemLine}></View>
            </View>
        )
    }

可以看到,我这里简单的展示了一个 title ,这个 title 是怎么来的呢?
在这里要感谢 玩安卓 提供的开放 Api ,让我可以实现分页加载!

    _getData() {
        console.log("_getData--page=" + this.page);
        //玩Android  首页文章列表接口,服务器资源紧张,时不时的会请求失败,不要急躁
        fetch("https://www.wanandroid.com/article/list/" + this.page + "/json")
            .then((response) => response.json())
            .then((responseJson) => {
                // console.log("success--" + JSON.stringify(responseJson));
                if (this.page == 0) {
                    console.log("从头加载!isCloseLoadMore=" + this.state.isCloseLoadMore + "--isRefresh=" + this.state.isRefresh);
                    this.setState({
                        isCloseLoadMore: false,
                        isLoadingMore:false,//加载完成时,可以继续加载
                        data: responseJson.data.datas
                    })
                } else {
                    console.log("加载更多!isCloseLoadMore=" + this.state.isCloseLoadMore + "--isRefresh=" + this.state.isRefresh);
                    this.setState({
                        isCloseLoadMore: false,
                        isLoadingMore:false,//加载完成时,可以继续加载
                        data: this.state.data.concat(responseJson.data.datas)//将新数据拼接到前数据,合并
                    })
                }

            })
            .catch((error) => {
                console.error("error--" + error);
                this.setState({
                    isRefresh:false,
                    isCloseLoadMore:false,
                    isLoadingMore:false,//加载失败时,可以继续加载
                })
            });
    }

这里是请求接口的方法,在请求成功之后,将 state 中的 data 更新。
可以看到,在请求成功中我还做了很多操作,这里是为了上拉加载做的判断。

 _loadMore() {
        console.log("_loadMore--data.length=" + this.state.data.length + "--page=" + this.page);
        if (!this.state.isCloseLoadMore && !this.state.isLoadingMore && this.state.data.length > 0) {
            this.page += 1;
            this._getData();
            this.setState({
                isLoadingMore:true //未加载完成时,不再触发接口
            })
        }
    }

这里是上拉加载的部分,通过 isCloseLoadMoreisLoadingMore 来控制是否可以上拉请求数据。

isCloseLoadMore主要是在当所有分页数据请求完之后,用来停止加载的(没有实现),而 isLoadingMore 是用来在上拉加载过程进行的时候,不能再次加载,之后接口成功或失败之后,才可以第二次请求!

其实在一开始的时候,对于onEndReachedThreshold这个属性,看文档真的看不懂,经过尝试之后,才有点明白它的意思。

其实就是判断当前加载的数据的最后一条,距离手机屏幕最底部的距离,当最后一条数据位于屏幕底部上方的时候(就是说当列表没铺满页面的时候),必定会触发onEndReached来加载数据。

而当超出屏幕的时候,就通过onEndReachedThreshold的值来判断是否触发onEndReached,当设置为0.5的时候,其实就是当列表的最后一条数据超出了屏幕的距离在50%以内,不会触发onEndReached,超出的部分超过50%了,就会触发。

接下来就是下拉刷新了,这个其实比上拉加载还能更简单点:

   _refresh() {
        console.log("_refresh--data.length=" + this.state.data.length + "--page=" + this.page);
        if (!this.state.isRefresh) {
            this.page = 0;
            this._getData();
        }
    }

FlatList中设置了onRefresh后,那就可以触发下拉刷新了,但是要注意的是,要搭配refreshing来使用,当下拉的时候,会触发refreshing,当为true的时候,则表示正在刷新,当为false的时候,表示刷新完了,当然,这个truefalse不是我们控制的!

其他的就是空布局、头部和尾部了,比较简单:

_emptyView() {
        return (
            <View style={styles.emptyViewContainer}>
                <Text style={styles.text}> 么得数据!</Text >
            </View>
        )
    }

    _headerView() {
        return (
            <View style={[styles.headerContainer, styles.itemBackground]}>
                <Text style={styles.text}>this  is  header  view</Text>
            </View>
        )
    }

    _footerView() {
        return (
            <View style={[styles.footerContainer, styles.itemBackground]}>
                <Text style={styles.text}>正在加载呢,你别拽了啊!</Text>
            </View>
        )
    }

好了,到此为止,一篇基本的FlatList的使用就写完了,希望对大家有用,毕竟本人也是新手,如有不对的地方,还请指出,欢迎探讨!
完整代码会放在 GitHub 上 abigbread!如果不能跳转的话,GitHub 搜索 abigbread 即可!

喜欢的话顺手点个赞或者 star 哦 ~

相关文章

网友评论

    本文标题:React Native 中的 FlatList

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