关于ScrollView中嵌套FlatList的一点经验
程序员文章站
2022-05-31 18:47:56
...
今天需要做一个包含滚动,上拉加载的界面,由于滚动区域包含一部分非上拉加载的模块,如下图所示
(请忽略我一会上拉一会下拉,统一视为上拉,懒得改图了。。。)
通过尝试多次,发现,ScrollView如果和FlatList嵌套的话需要注意:
- 两者嵌套后的关系
<View onStartShouldSetResponderCapture={() => {
this.setState({ enableScrollViewScroll: true });
}}>
<ScrollView scrollEnabled={this.state.enableScrollViewScroll}>
滚动区域
<View style={{backgroundColor:'#eeeeee'}}>
...这一部分是不上拉加载但需滚动区域 ,即下图绿色区域
<View style={{margin:8}}>
{ this.state.topics.length?this.renderFlatList():null}//这里请求到数据后通过函数自动生成需要上拉加载的部分模块,即下图黄色区域
</View>
</View>
</ScrollView>
</View>
加载函数为
renderFlatList=()=> {
console.log(this.state.enableScrollViewScroll)
console.log(this.state.scrollOffset)
return (
<View
onStartShouldSetResponderCapture={() => {
this.setState({ enableScrollViewScroll: false });//到FlatList区域后ScrollView和FlatList两区域的滚动区域重合,
//需要把外层的滚动设置为禁止滚动状态
}}>
<FlatList
backgroundColor={'green'}
data={this.state.topics}
renderItem={this._renderItem}
showsVerticalScrollIndicator={true}
numColumns ={2} // 一行3个
maxHeight={500}//此高度必须比第一次自动加载的撑起高度小
marginBotton={30}
keyExtractor={(item, index) => index.toString()}
onEndReachedThreshold={0.01}
onEndReached={this._reachend}
onMomentumScrollBegin={() => {
this.canLoadMore = true; //初始化时调用onEndReached的loadMore
}}
onScroll={this._onScroll2}
ref={this.myFlat}
refreshControl={//局部下拉加载。则把refresh正在加载的图标放到FlatList中
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.onRefresh}
/>
}
/>
</View>
);
}
触底函数为
_reachend=()=>{
console.log('_reachend')
if (this.canLoadMore && this.state.topics.length>=1) {//避免上拉时频繁加载,加载一次即终止
console.log('_reachend-in')
this.setState({
refreshing:true
})
this.gettopics(); //加载更多
this.canLoadMore = false;//一次上拉过程中,加载完一次立即阻止继续加载
}
}
产生data的函数为
_renderItem =({item}) =>(
<View style={{marginLeft:5,marginTop:10,borderRadius:20,borderWidth:1,borderColor:'transparent', overflow:'hidden',minHeight:185,backgroundColor:'white',width:width/2.2}}>
<Image source={{uri:item.picUrl}} style={{width:'100%',height:(800/1440)*(width/2.2), backgroundColor:'red'}}/>
<Text style={{width:width/2.2,marginLeft:5}}>{item.title}</Text>
<View style={{flex:1,flexDirection:'row',justifyContent:'space-around',marginTop:10}}>
<Image source={{uri:item.avatar}} style={{width:20,height:20,borderRadius:20}}/>
<Text>{item.nickname}</Text>
<Image style={{width:20,height:20}} source={require('../images/eyes.png')}/>
<Text>{Math.round(item.readCount/1000)}k</Text>
</View>
</View>
)
综上:
- FlatList的 maxHeight={500}//此高度必须比第一次自动加载的撑起高度小,才能保证其能正常滚动和下拉加载
- FlatList的 maxHeight={500}这个高度不要大到使不加载的区域从屏幕界面消失,否则将滚不回去
- 注意避免上拉加载过程中频繁加载,使用canLoadMore一个布尔值控制