前言
嗯...
怎么说呢,我换公司了,做为一个比较被动的人,这次入职后,发现要使用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
相当于 Android
中 listview
的 item
布局:
_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 //未加载完成时,不再触发接口
})
}
}
这里是上拉加载的部分,通过 isCloseLoadMore
、isLoadingMore
来控制是否可以上拉请求数据。
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
的时候,表示刷新完了,当然,这个true
和false
不是我们控制的!
其他的就是空布局、头部和尾部了,比较简单:
_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 哦 ~
网友评论