RN瀑布流
背景
电商以及图片网站经常可以看到瀑布流的列表,即多列等宽的列表,但是每一列中的元素高度不一定一致。这在 web 是一个很常见的设计且有很多组件可供使用,而在 ReactNative 中,少有成熟的瀑布流组件,大多数组件要么是多年前维护的,要么 star 数较少,或者干脆有一些不维护了,总之就是用着不放心。因此在产品同学的要求下,实现了一个 RN 瀑布流组件。这里只记录思路,具体代码后面添加了较多业务相关的,就不贴了。
需求
支持上拉加载,下拉刷新
支持多列可定制
性能尽量好
自定义元素
思路
整个瀑布流通过 FlatList 来实现,通过设置 columnsNum 与 renderItem,将每一列又分别渲染成一个 FlatList。内层并列的 FlatList 将会撑开且不会产生多余的滚动条,滚动时是外层的 FlatList。
接收 data 时,判断每一项应该属于哪一列, 如果项的高度不能提前获得,那么要在项的 onLayout 时获取高度,之后判断下一项属于哪一列
下拉采用 RN 提供的 RefreshControl 就可以完成,而上拉的事件,单列表可以通过 onReachEnd 触发,而对于我们这种实现方式则只能通过 onScroll 自行判断是否到达底部
// 由于 onEndReached 在渲染 data 项时会多次触发,且 props 及 state 未变化时不会触发,因此自行实现 const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => { const { nativeEvent: { contentOffset: { y: scrollTop }, contentSize: { height: scrollHeight }, layoutMeasurement: { height }, }, } = event; if (scrollHeight - height - scrollTop <= onEndReachedThreshold) { if (onEndReached) { onEndReached(event); } } if (props.onScroll) { props.onScroll(event); } };
这样一个简单的 瀑布流就完成了。