方法一簡(jiǎn)單介紹下未嵌套
ScrollView
的FlatList
上拉加載應(yīng)用場(chǎng)景,可自行忽略寻行,直接跳至方法二嵌套scrollView
場(chǎng)景省撑。
一、FlatList未嵌套在ScrollView的應(yīng)用場(chǎng)景
1丸相、最簡(jiǎn)單的方法是應(yīng)用react-native-refresh-list-view
組件實(shí)現(xiàn)搔确,其基于FlatList的二次封裝。
通過(guò)控制RefreshState
來(lái)實(shí)現(xiàn)下拉刷新或者上拉加載灭忠。
export const RefreshState = {
Idle: 0,
HeaderRefreshing: 1,
FooterRefreshing: 2,
NoMoreData: 3,
Failure: 4,
EmptyData: 5,
}
具體應(yīng)用的部分代碼如下:
import RefreshListView, { RefreshState } from "react-native-refresh-list-view";
renderRefreshList = () => {
const { sourceData, refreshState } = this.state;
return (
<RefreshListView
data={sourceData}
ItemSeparatorComponent={() => this.renderSeparator()}
keyExtractor={(item, idx) => idx.toString()}
renderItem={({ item }) => this.renderCell(item)}
ListHeaderComponent={this.renderHeader}
refreshState={refreshState}
onHeaderRefresh={this.onHeaderRefresh}
onFooterRefresh={() => this.onCheckMore()}
footerNoMoreDataText="已經(jīng)到底了"
/>
);
};
2膳算、如果不想使用方法1
中的第三方組件,可以自定義上拉加載的組件
核心屬性: onEndReachedThreshold
和onEndReached
當(dāng)onEndReachedThreshold
設(shè)置大于1時(shí)弛作,的確進(jìn)入頁(yè)面就觸發(fā)涕蜂,設(shè)置在0-1之間時(shí)按正常邏輯走。
<FlatList
...
onEndReachedThreshold={0.5}
...
/>
上拉加載更多onReached
被觸發(fā)兩次映琳,造成重復(fù)請(qǐng)求資源机隙,性能浪費(fèi)
<FlatList
...
onEndReached={() => {
if (this.canLoadMore) {
this.loadData(true); //
this.canLoadMore = false;
}
}}
onEndReachedThreshold={0.5}
onMomentumScrollBegin={() => {
this.canLoadMore = true; //初始化時(shí)調(diào)用onEndReached的loadMore
}}
...
/>
通常情況下是先調(diào)用onMomentumScrollBegin
,然后調(diào)用onEndReached
萨西,但是可能會(huì)存在意外情況
<FlatList
...
onEndReached={() => {
setTimeout(() => {
if (this.canLoadMore) {
this.loadData(true);
this.canLoadMore = false;
}
}, 100)
}}
onEndReachedThreshold={0.5}
onMomentumScrollBegin={() => {
this.canLoadMore = true; //初始化時(shí)調(diào)用onEndReached的loadMore
}}
...
/>
二有鹿、FlatList嵌套在ScrollView的應(yīng)用場(chǎng)景
當(dāng)FlatList
(或ListView
)和其他子組件在外面加了一個(gè)ScrollView
時(shí),debugg
發(fā)現(xiàn)在一直不停地觸發(fā)onEndReached
函數(shù)谎脯,也就是說(shuō)父組件ScrollView
能滾動(dòng)葱跋,導(dǎo)致FlatList
(或ListView
)中的數(shù)據(jù)不能滿屏,于是就不停地觸發(fā)該函數(shù)穿肄,不停fetch
請(qǐng)求年局。
還有,當(dāng)FlatList
(或ListView
)的dataSource
第一次渲染時(shí)咸产,如果為空矢否,也會(huì)觸發(fā)onEndReached
函數(shù)。
解決方案: 針對(duì)此問(wèn)題脑溢,直接對(duì)最外層的scrollview
實(shí)現(xiàn)上拉加載功能
renderScrollView = () => {
const { isRefreshing } = this.state;
return (
<ScrollView
onScroll={event => this.onScroll(event)}
scrollEventThrottle={1}
onMomentumScrollEnd={this.handleScrollEnd}
refreshControl={
<RefreshControl
tintColor="#FFFFFF"
refreshing={isRefreshing}
onRefresh={() => this.onRefresh()}
/>
}
>
{this.renderView()}
</ScrollView>
);
};
// 判斷上拉加載的時(shí)機(jī)
handleScrollEnd = event => {
const contentHeight = event.nativeEvent.contentSize.height;
const scrollViewHeight = event.nativeEvent.layoutMeasurement.height;
const scrollOffset = event.nativeEvent.contentOffset.y;
// 是否滑動(dòng)到底部
const isEndReached = scrollOffset + scrollViewHeight >= contentHeight;
// 內(nèi)容高度是否大于列表高度
const isContentFillPage = contentHeight >= scrollViewHeight;
const { reqSsqData, reqJpqData, reqWbqData, reqInData } = this.state;
if (isContentFillPage && isEndReached) {
// 已滑動(dòng)scrollview底部僵朗,觸發(fā)加載分頁(yè)請(qǐng)求
}
};
需要注意:
在判斷上拉加載的時(shí)機(jī)時(shí)赖欣,主要是比較以下2個(gè)時(shí)機(jī),根據(jù)自己的需求添加
// 滾動(dòng)結(jié)束的回調(diào)
onMomentumScrollEnd={this.handleScrollEnd}
// 手指松開(kāi)屏幕的回調(diào)
onScrollEndDrag={this.handleScrollEnd}
參考:
http://www.reibang.com/p/33ec6ceeb638
https://www.cnblogs.com/fe-linjin/p/10587720.html
https://blog.csdn.net/qq_21478985/article/details/80931386