rntpc_flash-list:基于 Shopify flash-list 的 OpenHarmony 适配版,高性能列表组件,替代 FlatList 无白屏、更省内存

基于 Shopify flash-list 的 OpenHarmony 适配版,高性能列表组件,替代 FlatList 无白屏、更省内存

分支4Tags6

文档模板: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

约束与限制

兼容性

本文档内容基于以下版本验证通过:

  1. RNOH: 0.84.3; SDK: HarmonyOS 6.0.2 Release SDK; IDE: DevEco Studio 6.0.2.650; ROM: Mate60 Pro 7.0.0;
  2. 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) ,请自由地享受和参与开源。

项目介绍

基于 Shopify flash-list 的 OpenHarmony 适配版,高性能列表组件,替代 FlatList 无白屏、更省内存

定制我的领域