基于 Shopify flash-list 的 OpenHarmony 适配版,高性能列表组件,替代 FlatList 无白屏、更省内存
当前访问频次受限,请登录后继续访问
文档模板:v0.4.2
@shopify/flash-list
本项目基于 @shopify/flash-list 开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/flash-list,版本所属关系如下:
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
|---|---|---|---|---|---|---|---|
| @react-native-ohos/flash-list | ~2.2.0 (开发中) | GitCode Releases | 0.84.* /0.86.* | 否 | API12+ | 2.3.2 | master |
| @react-native-ohos/flash-list | ~2.1.1 | GitCode Releases | 0.82.* | 否 | API12+ | 2.1.0 | br_rnoh0.82 |
| @react-native-ohos/flash-list | ~1.8.3 | GitCode Releases | 0.77.* | 否 | API12+ | 1.8.2 | br_rnoh0.77 |
| @react-native-ohos/flash-list | ~1.6.4 | GitCode Releases | 0.72.* | 是 | API12+ | 1.6.3 | br_rnoh0.72 |
| @react-native-oh-tpl/flash-list | 1.6.3-0.2.9@deprecated | Github Releases(deprecated) | 0.72.* | 否 | API12+ | 1.6.3 | sig |
简介
FlashList 是 Shopify 开发的高性能 React Native 列表组件,是 FlatList 的现代替代方案。它通过高效的回收机制和智能化渲染,实现流畅的 60fps 滚动体验,同时大幅降低内存占用。
主要特性:
- 高性能:通过回收复用列表项,实现接近原生的滚动性能。
- 低内存:智能化渲染策略,仅渲染可见区域及预渲染范围内的项目。
- 简单易用:API 设计与 FlatList 高度一致,迁移成本低。
- 多列与瀑布流:支持多列布局(numColumns)和瀑布流布局(masonry 属性)。
下载安装
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/flash-list
yarn
yarn add @react-native-ohos/flash-list
约束与限制
兼容性
本文档内容基于以下版本验证通过:
- RNOH: 0.84.3; SDK: HarmonyOS 6.0.2 Release SDK; IDE: DevEco Studio 6.0.2.650; ROM: Mate60 Pro 7.0.0;
- RNOH: 0.86.1; SDK: HarmonyOS 6.0.2 Release SDK; IDE: DevEco Studio 6.0.2.650; ROM: Mate60 Pro 7.0.0;
使用示例
下面的代码展示了这个库的基本使用场景:
使用时 import 的库名不变。
import React from "react";
import { View, Text } from "react-native";
import { FlashList } from "@shopify/flash-list";
const DATA = [
{
title: "First Item",
},
{
title: "Second Item",
},
];
const MyList = () => {
return (
<FlashList
data={DATA}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
);
};
export default MyList;
属性
"Platform"列表示该属性在原三方库上支持的平台。
"OpenHarmony Support"列为 yes 表示 OpenHarmony 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 |
|---|---|---|---|---|---|---|
| contentContainerStyle | StyleProp<ViewStyle> | None | No | All | Yes | 可通过 contentContainerStyle 为整个内容区域设置内边距。 |
| horizontal | boolean | false | No | All | Yes | 设置为 true 时,项目将水平并列排列而非垂直堆叠。 |
| keyExtractor | function | None | No | All | Yes | 用于为指定索引位置的项生成唯一键值。键值用于优化性能。未定义时默认使用索引作为键。 |
| numColumns | number | 1 | No | All | Yes | 多列布局只能在 horizontal={false} 的情况下渲染,并且会像 flexWrap 布局一样呈现“之”字形排列。所有子项的高度必须一致——不支持瀑布流(masonry)布局。 |
| extraData | any | None | No | All | Yes | 用于指示列表重新渲染的标记属性。 |
| drawDistance | number | 250 | No | All | Yes | 预渲染的绘制距离(dp/px)。 |
| viewabilityConfig | object | None | No | All | Yes | 用于判定项目可见性的默认配置。支持 minimumViewTime、viewAreaCoveragePercentThreshold、itemVisiblePercentThreshold、waitForInteraction 等字段。运行时动态更改此配置不受支持。 |
| renderItem | function | None | Yes | All | Yes | 从 data 中获取项目并渲染至列表。回调参数 info 包含 item、index、target、extraData 字段。target 为渲染目标枚举,可选值:"Cell"(列表项)、"StickyHeader"(粘性头部)、"Measurement"(尺寸测量,v2 已弃用)。 |
| data | ItemT[] | None | Yes | All | Yes | 数据源,为指定类型的简单项目数组。 |
| CellRendererComponent | JSX Element | 内置默认组件 | No | All | Yes | 每个单元格的渲染元素。可以是 React 类组件、渲染函数或 memo 等包装组件(ExoticComponent)。 |
| ListFooterComponent | JSX Element | None | No | All | Yes | 在列表底部渲染的组件。可以是 React 组件类、React 元素或 memo 等包装组件(ExoticComponent)。 |
| ListHeaderComponent | JSX Element | None | No | All | Yes | 在列表顶部渲染的组件。可以是 React 组件类、React 元素或 memo 等包装组件(ExoticComponent)。 |
| refreshControl | JSX Element | None | No | All | Yes | 自定义下拉刷新控件元素(继承自 ScrollViewProps)。 |
| renderScrollComponent | JSX Element | ScrollView | No | All | Yes | 作为主滚动视图渲染的组件。可以是 React 组件类、渲染函数或 memo 等包装组件(ExoticComponent)。 |
| onEndReached | callback | None | No | All | Yes | 当滚动位置接近渲染内容末尾(距离阈值为 onEndReachedThreshold)时触发一次。 |
| onEndReachedThreshold | number | 0.5 | No | All | Yes | 触发 onEndReached 回调时,列表底部边缘与内容末尾的距离阈值(以列表可见长度为单位)。 |
| onViewableItemsChanged | callback | None | No | All | Yes | 当项目的可见性发生变化时触发(可见性由 viewabilityConfig 属性定义)。回调参数包含 viewableItems 和 changed 数组,元素为 ViewToken 对象(含 item、key、index、isViewable、timestamp 字段)。 |
| getItemType | function | None | No | All | Yes | 允许开发者指定项目类型以优化回收。接收 item、index、extraData 参数,返回类型标识。相同类型的项会相互回收,默认类型为 0。 |
| overrideItemLayout | function | None | No | All | Yes | 用于更改项目列跨度。接收 layout、item、index、maxColumns、extraData 参数,v1 版本支持设置 layout.span 和 layout.size;v2 版本仅支持 layout.span。 |
| ItemSeparatorComponent | JSX Element | None | No | All | Yes | 在每项之间(不包括顶部和底部)渲染的分隔组件。默认提供 leadingItem 和 trailingItem 属性。支持 memo 等包装组件(ExoticComponent)。 |
| ListEmptyComponent | JSX Element | None | No | All | Yes | 列表为空时渲染的组件。可以是 React 组件类、React 元素或 memo 等包装组件(ExoticComponent)。 |
| ListEmptyComponentStyle | StyleProp | None | No | All | Yes | 列表为空时渲染组件内部容器的样式。 |
| ListFooterComponentStyle | StyleProp | None | No | All | Yes | 列表底部组件内部容器的样式。 |
| ListHeaderComponentStyle | StyleProp | None | No | All | Yes | 列表顶部组件内部容器的样式。 |
| stickyHeaderIndices | number[] | None | No | All | Yes | 指定作为吸顶(sticky)头部的项目索引数组(继承自 ScrollViewProps)。设置后 FlashList 将实现吸顶效果;horizontal 列表下使用会抛出错误。 |
| stickyHeaderConfig | object | None | No | All | Yes | 吸顶头部配置对象。子属性:useNativeDriver(动画是否使用原生驱动,默认 true)、offset(吸顶位置距顶部偏移,默认 0)、backdropComponent(吸顶背后的组件,如模糊/背景效果)、zIndex(吸顶容器层级,默认 2)、hideRelatedCell(吸顶时隐藏关联单元格,默认 false)。 |
| onChangeStickyIndex | callback | None | No | All | Yes | 当前吸顶头部发生变化时触发,参数为当前吸顶索引和上一个吸顶索引。 |
| initialScrollIndex | number | None | No | All | Yes | 不从首项开始显示,而是从 initialScrollIndex 指定位置开始。 |
| inverted | boolean | false | No | All | Yes | 反转滚动方向,作用于列表容器、头部/底部/空组件及吸顶头部。 |
| onLoad | callback | None | No | All | Yes | 当列表在屏幕上完成项目绘制后触发。回调参数 elapsedTimeInMs 为绘制耗时(毫秒)。 |
| onRefresh | callback | None | No | All | Yes | 提供此回调可添加标准 RefreshControl 实现"下拉刷新"功能。需确保同时正确设置 refreshing 属性。 |
| onScroll | callback | None | No | All | Yes | 滚动期间每帧最多触发一次(继承自 ScrollView)。 |
| overrideProps | object | None | No | All | Yes | 覆盖列表内部 ScrollView 的属性。 |
| progressViewOffset | number | None | No | Android | Yes | 当加载指示器需要偏移量时才需设置此属性。 |
| refreshing | boolean | false | No | All | Yes | 在等待刷新数据时设置为 true。 |
| viewabilityConfigCallbackPairs | object | None | No | All | Yes | ViewabilityConfig/onViewableItemsChanged 配置对集合。每个配置对包含 viewabilityConfig 和 onViewableItemsChanged 两个属性。当对应配置条件满足时,触发对应回调。 |
| FlashListRef | React.RefObject<FlashList<T>> | None | No | All | Yes | 提供对 FlashList 实例的引用,支持直接操作列表。 |
| onStartReached | callback | None | No | All | Yes | 当滚动位置接近内容起始位置时触发一次的回调。 |
| onStartReachedThreshold | number | 0.2 | No | All | Yes | 触发 onStartReached 回调时,列表顶部边缘与内容起始位置的距离阈值(以列表可见长度为单位)。 |
| maintainVisibleContentPosition | object | 默认启用 | No | All | Yes | 用于在内容变化时维持滚动位置的配置。支持配置 disabled、autoscrollToTopThreshold、autoscrollToBottomThreshold、animateAutoScrollToBottom(默认 true)和 startRenderingFromBottom 等子属性。 |
| masonry | boolean | false | No | All | Yes | 启用瀑布流布局模式。 |
| maxItemsInRecyclePool | number | 无限制 | No | All | Yes | 回收池中缓存的最大项目数。当项目滚动出屏幕时会被缓存在回收池中。设置为 0 将禁用回收池,项目滚出屏幕后将直接卸载。 |
| onCommitLayoutEffect | function | None | No | All | Yes | 当布局提交完成时调用的回调。 |
| LayoutCommitObserver | React.Component | None | No | All | Yes | 用于观察 FlashList 何时提交布局的组件。 |
| LayoutCommitObserverProps | object | None | No | All | Yes | 定义 LayoutCommitObserver 的属性接口,包含回调函数。 |
| initialScrollIndexParams | object | None | No | All | Yes | initialScrollIndex 的附加配置。可使用 viewOffset 对初始滚动位置应用偏移量。仅当设置了 initialScrollIndex 时生效。 |
| optimizeItemArrangement | boolean | false | No | All | Yes | 启用后,FlashList 在瀑布流(masonry)布局下将通过调整项目顺序来减少列高差异。仅在该模式下可用。 |
| style | StyleProp<ViewStyle> | None | No | All | Yes | RecyclerView 父容器的样式。 |
| props | RecyclerViewProps<T> | / | No | All | Yes | 获取当前列表的 props 配置(通过 FlashListRef 访问)。 |
HOOKS
"Platform"列表示该属性在原三方库上支持的平台。
"OpenHarmony Support"列为 yes 表示 OpenHarmony 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| useLayoutState | Hook | initialState:初始状态值或返回初始状态的函数 | [state, setLayoutState] | No | All | Yes | 将状态管理与 RecyclerView 布局更新结合的自定义 Hook。状态变化时会自动触发布局重新计算;setLayoutState 的第二个参数 skipParentLayout 可跳过父布局更新。 |
| useRecyclingState | Hook | initialState:初始状态;deps:依赖数组;onReset:重置回调(可选) | [state, setState] | No | All | Yes | 提供自动重置功能的状态管理 Hook。类似 useState,但在指定依赖项 deps 变化时会自动重置状态,并触发可选的 onReset 回调。可避免项目回收时多余的 setState 调用。 |
| useMappingHelper | Hook | / | { getMappingKey } | No | All | Yes | 返回包含 getMappingKey 函数的对象,用于在 .map 操作创建组件列表时生成最优键值。在 FlashList 内部返回 index 以优化回收性能,在外部返回 itemKey 以保持稳定键。 |
| useFlashListContext | Hook | / | FlashListContext<T> | undefined | No | All | Yes | 获取当前 FlashList 上下文的 Hook。可访问 layout()、getRef()、getParentRef()、getScrollViewRef() 和 getParentScrollViewRef() 等方法。 |
| useBenchmark | Hook | flashListRef;callback:结果回调;params:startDelayInMs(默认 3000)、speedMultiplier、repeatCount、startManually 等 |
{ startBenchmark, isBenchmarkRunning } | No | All | Yes | 对 FlashList 运行滚动基准测试,测试结果通过 callback 传入,含可直接打印的 formattedString。 |
| useDataMultiplier | Hook | data:原始数据数组;count:目标条数 | [T[]] | No | All | Yes | 通过复制将原始数据放大到指定条数,用于为基准测试构造大数据集。对象类型数据会逐项浅拷贝以避免引用重复;与 FlatList 配合使用时需移除 keyExtractor,以防复制后 id 重复。 |
| useFlatListBenchmark | Hook | flatListRef;callback:结果回调;params:必填 targetOffset,其余同 useBenchmark |
{ startBenchmark, isBenchmarkRunning } | No | All | Yes | 对 RN FlatList 运行滚动基准测试,用于与 FlashList 进行性能对比。建议测试期间移除分页逻辑(最简单的方式是移除 onEndReached 回调)。结果通过 callback 传入。 |
| autoScroll | function | scroll:滚动函数;fromX/fromY:起点坐标;toX/toY:终点坐标;speedMultiplier(默认 1);cancellable | Promise<boolean> | No | All | Yes | 自动滚动辅助函数(useBenchmark 内部使用)。以可控速度将任意可滚动元素从起点滚动到终点,可传入 Cancellable 实例中途取消滚动。 |
方法
"Platform"列表示该属性在原三方库上支持的平台。
"OpenHarmony Support"列为 yes 表示 OpenHarmony 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| prepareForLayoutAnimationRender | function | / | void | No | All | Yes | 在执行布局动画前调用此方法(禁用项目回收以防止视觉异常),例如删除元素时为其添加动画效果。 |
| recordInteraction | function | / | void | No | All | Yes | 通知列表已发生交互行为,这将触发可见性计算(例如当 waitForInteraction 为 true 且用户未滚动时)。 |
| scrollToEnd | function | ScrollToEdgeParams:animated(默认 false) |
void | No | All | Yes | 滚动至内容末尾。 |
| scrollToIndex | function | ScrollToIndexParams:index(必填)、animated(默认 false)、viewPosition(默认 0,可选 0/0.5/1)、viewOffset |
Promise<void> | No | All | Yes | 滚动至指定索引位置。v1 和 v2 版本对 viewOffset 参数的处理存在差异,方向相反。Promise 在滚动完成后 resolve。 |
| scrollToItem | function | ScrollToItemParams:item(必填)、animated、viewPosition、viewOffset |
void | No | All | Yes | 滚动至指定项目。v1 和 v2 版本对 viewOffset 参数的处理存在差异,方向相反。 |
| scrollToOffset | function | ScrollToOffsetParams:offset(必填)、animated(默认 false)、skipFirstItemOffset(默认 true,为 true 时偏移量不计入首项偏移即头部/内边距) |
void | No | All | Yes | 滚动至列表内特定的内容像素偏移量。 |
| recomputeViewableItems | function | / | void | No | All | Yes | 强制重新计算可见项目并触发可见性回调。适用于在不触发滚动事件的操作(如手动修改项目尺寸)后调用。 |
| getLayout | function | index:项目索引 | RVLayout | undefined | No | All | Yes | 获取指定索引项目的布局信息(含 x、y、width、height)。 |
| getChildContainerDimensions | function | / | { width, height } | No | All | Yes | 返回子容器的尺寸。 |
| getScrollableNode | function | / | 可滚动节点 | No | All | Yes | 返回底层可滚动节点,主要用于平台特定集成。 |
| getFirstItemOffset | function | / | number | No | All | Yes | 返回第一个项目的偏移量(包含头部/内边距)。 |
| getWindowSize | function | / | { width, height } | No | All | Yes | 返回当前视口尺寸。 |
| getFirstVisibleIndex | function | / | number | No | All | Yes | 返回第一个可见项目的索引。 |
| getAbsoluteLastScrollOffset | function | / | number | No | All | Yes | 返回最后一次滚动的绝对偏移量,可用于自定义滚动追踪。 |
| clearLayoutCacheOnUpdate | function | / | void | No | All | Yes | 在更新时清除布局缓存。适用于轮播等方向变化场景;应在 render 前调用,而非 effect 中。 |
| computeVisibleIndices | function | / | { startIndex, endIndex } | No | All | Yes | 返回当前可见项目的索引范围。 |
| flashScrollIndicators | function | / | void | No | All | Yes | 使滚动指示器短暂闪烁显示,用于提示用户还有更多内容可滚动。 |
| getNativeScrollRef | function | / | CompatScroller | null | No | All | Yes | 返回底层原生滚动视图引用。常规场景不推荐使用。 |
| getScrollResponder | function | / | 滚动响应器 | No | All | Yes | 返回滚动响应器引用,用于高级滚动处理与集成。 |
| scrollToTop | function | ScrollToEdgeParams:animated(默认 false) |
void | No | All | Yes | 滚动至列表顶部(或起始位置)。 |
辅助类型
以下辅助类型均由本库导出,与上述属性、Hooks 和方法配合使用。
ListRenderItem
renderItem 属性的回调类型:(info: ListRenderItemInfo<TItem>) => React.ReactElement | null。从 data 中获取项目并渲染至列表。info 参数包含以下字段:
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| item | TItem | 是 | 当前正在渲染的 data 中的项目。 |
| index | number | 是 | 项目在数据数组中的索引。 |
| target | RenderTarget | 是 | 本次渲染的渲染目标。可选值:"Cell"(列表项)、"StickyHeader"(粘性头部)、"Measurement"(尺寸测量,不可见;v2 已弃用)。 |
| extraData | any | 否 | 传递给 FlashList 的 extraData 属性。 |
RenderTargetOptions
渲染目标的枚举常量对象,类型为 Record<string, RenderTarget>(RenderTarget = "Cell" \| "StickyHeader" \| "Measurement")。可用于与 ListRenderItemInfo 的 target 字段进行比较(例如 info.target === RenderTargetOptions.Cell)。
| 名称 | 值 | 描述 |
|---|---|---|
| Cell | "Cell" | 渲染为列表项。 |
| StickyHeader | "StickyHeader" | 渲染为粘性头部。可用于在项目作为粘性头部时改变其外观。 |
| Measurement | "Measurement" | 为测量尺寸而渲染,不会显示。统计分析中可忽略(v2 已弃用)。 |
JSFPSResult
基准测试(通过 JSFPSMonitor)采集的 JS 线程帧率统计结果,作为 BenchmarkResult 的 js 字段返回。所有数值均保留一位小数。
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| minFPS | number | 是 | 测试期间观测到的最低 JS FPS。 |
| maxFPS | number | 是 | 测试期间观测到的最高 JS FPS。 |
| averageFPS | number | 是 | 测试期间的平均 JS FPS。 |
Cancellable
用于取消进行中异步操作的工具类,例如取消 useBenchmark/useFlatListBenchmark 发起的基准测试滚动,或取消 autoScroll 辅助函数的滚动(将实例传入 autoScroll 即可中途取消滚动)。
| 名称 | 类型 | 参数类型 | 返回值 | 描述 |
|---|---|---|---|---|
| cancel | 方法 | / | void | 将操作标记为已取消。 |
| isCancelled | 方法 | / | boolean | 返回操作是否已被取消。 |
| _isCancelled | 属性 | / | boolean | 内部取消状态标记(初始值为 false)。 |
BenchmarkParams
useBenchmark 的配置参数,所有字段均为可选。
| 名称 | 类型 | 默认值 | 必填 | 描述 |
|---|---|---|---|---|
| startDelayInMs | number | 3000 | 否 | 基准测试自动启动前的延迟时间(毫秒)。 |
| speedMultiplier | number | 1 | 否 | 用于提高或降低滚动速度。 |
| repeatCount | number | 1 | 否 | 基准测试重复执行的次数。 |
| sumNegativeBlankAreaValues | boolean | false | 否 | 为 true 时,累计空白区域将计入负空白面积之和。当列表绘制速度快于滚动速度时,空白面积为负。 |
| startManually | boolean | false | 否 | 为 true 时基准测试不会自动启动,需调用返回的 startBenchmark 函数手动触发。 |
BenchmarkResult
基准测试结果,通过传给 useBenchmark/useFlatListBenchmark 的回调返回。
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| js | JSFPSResult | 否 | JS FPS 统计结果,参见 JSFPSResult。 |
| interrupted | boolean | 是 | 基准测试是否在完成前被取消。 |
| suggestions | string[] | 是 | 根据测试数据生成的优化建议。 |
| formattedString | string | 否 | 可直接打印的结果摘要字符串,可输出到控制台或以弹窗展示。仅在基准测试未被中断时设置。 |
FlatListBenchmarkParams
useFlatListBenchmark 的配置参数。继承 BenchmarkParams(含其全部字段),并新增:
| 名称 | 类型 | 必填 | 描述 |
|---|---|---|---|
| targetOffset | number | 是 | 基准测试滚动至该目标偏移量后再滚动回 0。 |
遗留问题
其他
无
目录结构
/rntpc_flash-list # 项目根目录
├── src # RN 代码
│ └─ index.ts # 入口文件
│ └─ FlashList.ts # FlashList 组件
│ └─ AnimatedFlashList.ts # AnimatedFlashList 动画列表组件
│ └─ FlashListProps.ts # 属性类型定义
│ └─ FlashListRef.ts # FlashList Ref 类型定义
│ └─ isNewArch.ts # 新架构检测
│ └─ recyclerview/ # RecyclerView 核心实现(布局管理、ViewHolder、可见性管理等)
│ └─ native/ # 原生配置
│ │ └─ config/ # 平台配置
│ └─ benchmark/ # 性能基准测试工具
│ └─ errors/ # 错误定义
│ └─ utils/ # 工具方法
├── example # 示例应用
├── shared # 共享配置
├── README.md # 中文安装使用方法
├── README_en.md # 英文安装使用方法
├── CHANGELOG.md # 更新日志
├── LICENSE # 开源协议
贡献代码
使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。
开源协议
本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。