背景
瀑布流是一种流行的应用设计方式,特点是在垂直方向排列内容,而且每一行的列数可能不同,形成类似瀑布般的效果。瀑布流结构的优点有以下几点:
- 优化空间利用:瀑布流布局可充分利用屏幕空间,尤其是在多栏目显示有限基础上的互联网应用中。它能够有效填充各种尺寸的屏幕,使得页面内容布局更加美观。
- 提升用户体验:相比传统的分页式展示,瀑布流提供了无缝滚动体验,可以避免跳转和等待页面加载的不便,用户滚动浏览的过程中,新的内容会不断加载出来。
- 强化视觉冲击力:瀑布流布局多以图片为主,配合不规则的排版布局,可以强化视觉效果,使页面更加生动、丰富,有助于吸引并保留用户。
- 方便内容筛选:在瀑布流布局中,用户可以一眼扫过大量内容,便于进行快速筛选,有助于提升信息获取的效率。
采用瀑布流结构,有助于提升网站页面的美观度、易用性以及用户体验度,所以大家都喜欢这种方式来展示页面内容。
那么都有哪些公司在使用瀑布流呢?
抖音推荐页
快手发现页
小红书发现页
所以我也是基于react native的flatlist实现了一个瀑布流组件👏 喜欢的记得三连哦 感恩感谢🧣🥳🥳🥳 。
效果展示
两列瀑布流
三列瀑布流
使用说明
- 组件基于flatlist实现
几乎支持flatlist所有属性仅个别属性不支持 例如 horizontal 目前仅支持垂直方向 - 基于ts + hooks实现 有较好的类型提示
- 支持不定高item 内部通过布局自动计算 所以 getItemLayout 设置无效
- 关于ref的支持 默认取到的是WaterFallList的ref 内部包括自定义的属性和flatlistRef. 如果想获取内部flatlist的ref对象 可以通过WaterFallList内部转发的的 flatListRef 对象
<WaterFallList
ref={waterfallRef}
ItemSeparatorComponent={() => <View />}
initialNumToRender={10}
windowSize={10}
onScroll={onScroll}
renderItem={({ item }) => <Item data={item}></Item>}
data={list}
contentContainerStyle={{ flexGrow: 1 }}
onEndReachedThreshold={0.5}
onEndReached={onEndReached}
numColumns={2}
showsVerticalScrollIndicator={false}
ListEmptyComponent={() => <View />}
ListFooterComponent={() => <View />}
/>;
注意事项
- item最大高度与最小高度差值不宜过大 建议:
最小高度>=最大高度的30% - item渲染完成后
不建议动态改变item的高度会引起布局抖动 - 内部封装了refreshList函数 在刷新列表前 建议先调用此函数(刷新调用即可 列表项增加不需要调用)
- 仅支持垂直瀑布流
- 因为 rn 官方点击组件在 Android 上超出父容器无法点击的问题,组件内部的触摸组件需要使用
react-native-gesture-handler中的替换 rn 官方组件
import {
TouchableNativeFeedback,
TouchableHighlight,
TouchableOpacity,
TouchableWithoutFeedback,
} from "react-native";
// has to be replaced with:
import {
TouchableNativeFeedback,
TouchableHighlight,
TouchableOpacity,
TouchableWithoutFeedback,
} from "react-native-gesture-handler";
原理
- 首先更改数据源 将单列表数组转换为N维数组确定每行的具体item数
- 第一次渲染 获取到每个元素的真实高度信息(获取定位信息的方式可以参考这篇文章),并通过_itemHeightsRef记录下来。
- 当高度信息收集完成 触发强制刷新 再次渲染一次列表
- 决策当前元素应该放在第几列 每行的高度是多少 当前元素距离容器顶部间距是多少 当前行距离容器顶部间距是多少
例如当前一行是这个形式:
第三个元素应该加在下一行的最短一列:
同理第四个元素也加在最短的一列 第二列:
然后计算第二行的行高:
因为flatlist的一行是以最长的元素高度为准 所以我们需要计算出最长的元素高度是多少 并且还要减去上一行的高度这个偏移量。
所以高度如下
然后不断循环列表 直到结束。
github源码
react-native-waterfall-list-view