新闻详情

新闻详情

首页 / 资讯中心 / 详情

react-native-bottom-sheet 集成指南:用 BottomSheetFlashList 构建可手势联动的 FlashList 高性能列表

发布时间:2026/9/25 3:10:02来源:尧图网络
react-native-bottom-sheet 集成指南:用 BottomSheetFlashList 构建可手势联动的 FlashList 高性能列表
前端移动开发UI组件跨平台【免费下载链接】react-native-bottom-sheetA performant interactive bottom sheet with fully configurable options 项目地址https://gitcode.com/gh_mirrors/re/react-native-bottom-sheet点击查看免费下载BottomSheetFlashList是 react-native-bottom-sheet 提供的预集成滚动组件它在shopify/flash-list的FlashList之上无缝接入了BottomSheet的拖拽手势、滚动状态与吸附snap逻辑是需要在底部弹层中渲染大量列表数据的首选方案。本文将以 website/docs/components/bottomsheetflashlist.md 为主线结合仓库源码与官方示例完整讲解它的 Props、安装方式、与 React Navigation 的配合技巧以及底层实现原理读完即可在项目中落地一个高性能的底部弹层列表。一、什么是 BottomSheetFlashListBottomSheetFlashList是 react-native-bottom-sheet 中与BottomSheetScrollView、BottomSheetFlatList、BottomSheetSectionList、BottomSheetVirtualizedList并列的预集成滚动组件统一从 src/components/bottomSheetScrollable/index.ts 导出。其官方定位是A pre-integratedFlashListcomponent withBottomSheetgestures.即一个已经与BottomSheet手势深度集成的FlashList。它直接继承了FlashListProps因此你熟悉的data、renderItem、keyExtractor、estimatedItemSize、onEndReached、ListFooterComponent、ItemSeparatorComponent等所有 FlashList 能力都原样可用无需额外适配。一个典型的代码形态是import BottomSheet, { BottomSheetFlashList } from gorhom/bottom-sheet; BottomSheet ref{sheetRef} snapPoints{snapPoints} enableDynamicSizing{false} BottomSheetFlashList data{data} keyExtractor{keyExtractor} renderItem{renderItem} estimatedItemSize{43.3} / /BottomSheet二、安装前置条件必须先安装 shopify/flash-list需要特别强调的是shopify/flash-list并不是react-native-bottom-sheet 的强制依赖。在 src/components/bottomSheetScrollable/BottomSheetFlashList.tsx 的源码中库采用了 Metro 的可选导入optional import机制let FlashList: { FlashList: React.FC }; try { FlashList require(shopify/flash-list) as never; } catch (_) {}当检测不到shopify/flash-list时组件会在渲染期直接抛出错误提示安装useMemo(() { if (!FlashList) { throw You need to install FlashList first, yarn install shopify/flash-list; } }, []);因此在你的项目中必须先自行安装 FlashList例如yarn install shopify/flash-list官方示例仓库中锁定的是shopify/flash-list1.7.1见 example/package.json可供参考。安装完成后BottomSheetFlashList会将renderScrollComponent注入 FlashList 内部把实际滚动载体替换为BottomSheetScrollView从而让 FlashList 获得 bottom sheet 的手势上下文。三、Props 详解BottomSheetFlashList的 Props 由两部分组成FlashList 原生 Props bottom sheet 专有的滚动配置。3.1 继承 FlashListProps组件类型定义继承了 FlashList 的全部 Props见 src/components/bottomSheetScrollable/BottomSheetFlashList.tsx唯一被剥离的是decelerationRate、onScroll、scrollEventThrottle这三个属性——因为它们由 bottom sheet 的滚动状态驱动以实现解锁/锁定滚动时不同减速率的原生手感。其余如data/renderItem/keyExtractorestimatedItemSizeFlashList 高性能的关键务必提供onEndReached/ListFooterComponent/ListEmptyComponentItemSeparatorComponent/viewabilityConfig均按 FlashList 语义原样使用。3.2 focusHook属性类型默认值必填focusHookfunctionReact.useEffect否官方文档原话当 bottom sheet 与多个滚动组件multiple scrollables一起使用时需要该属性来让 bottom sheet 正确识别当前的滚动 ref尤其是在配合 React Navigation 使用时。原理层面滚动 ref 的注册逻辑位于 src/hooks/useScrollableSetter.ts其签名中的最后一个参数就是 focus hookexport const useScrollableSetter ( ref, type, contentOffsetY, refreshable, useFocusHook useEffect ) { // ... useFocusHook(handleSettingScrollable); };handleSettingScrollable内部会通过findNodeHandle拿到滚动节点的原生 id并调用setScrollableRef将其注册为 bottom sheet 当前的活动滚动源同时把滚动偏移、滚动类型、是否可下拉刷新等状态同步到共享值上。默认使用useEffect意味着组件只要挂载就会被注册但当多个页面/弹层各自持有滚动组件时非焦点页面的滚动组件也可能抢占注册导致手势联动错乱。此时应从react-navigation/native引入useFocusEffect并传入让注册行为与页面/弹层获得焦点同步import { useFocusEffect } from react-navigation/native; BottomSheetFlashList focusHook{useFocusEffect} /* ... */ /仓库示例 example/src/components/contactList/ContactList.tsx 中便以focusHook{useFocusEffect}的方式将ContactList内的滚动列表接入 bottom sheet可作为真实场景的对照实现。3.3 其他继承的滚动专有 Props在 src/components/bottomSheetScrollable/types.d.ts 中BottomSheetScrollableProps还定义了以下两个属性同样适用于BottomSheetFlashListenableFooterMarginAdjustment?: boolean默认false自动为滚动内容底部增加 margin避免内容被动画 footer 遮挡。开启后底层实现会通过useAnimatedStyle将animatedFooterHeight.value映射为容器的marginBottom见 src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx。scrollEventsHandlersHook?: ScrollEventsHandlersHookType默认useScrollEventsHandlersDefault自定义滚动事件处理钩子可用于高级定制滚动行为。这是一个实验性 API签名可能在主版本内变动。四、完整示例以下代码来自官方文档可在你的 App 中直接运行——它演示了 50 条字符串数据、双吸附点25% / 50%以及通过 ref 控制吸附与关闭的完整闭环import React, { useCallback, useRef, useMemo } from react; import { StyleSheet, View, Text, Button } from react-native; import { GestureHandlerRootView } from react-native-gesture-handler; import BottomSheet, { BottomSheetFlashList } from gorhom/bottom-sheet; const keyExtractor (item) item; const App () { // hooks const sheetRef useRefBottomSheet(null); // variables const data useMemo( () Array(50) .fill(0) .map((_, index) index-${index}), [] ); const snapPoints useMemo(() [25%, 50%], []); // callbacks const handleSnapPress useCallback((index) { sheetRef.current?.snapToIndex(index); }, []); const handleClosePress useCallback(() { sheetRef.current?.close(); }, []); // render const renderItem useCallback(({ item }) { return ( View key{item} style{styles.itemContainer} Text{item}/Text /View ); }, []); return ( GestureHandlerRootView style{styles.container} Button titleSnap To 50% onPress{() handleSnapPress(1)} / Button titleSnap To 25% onPress{() handleSnapPress(0)} / Button titleClose onPress{() handleClosePress()} / BottomSheet ref{sheetRef} snapPoints{snapPoints} enableDynamicSizing{false} BottomSheetFlashList data{data} keyExtractor{keyExtractor} renderItem{renderItem} estimatedItemSize{43.3} / /BottomSheet /GestureHandlerRootView ); }; const styles StyleSheet.create({ container: { flex: 1, paddingTop: 200, }, contentContainer: { backgroundColor: white, }, itemContainer: { padding: 6, margin: 6, backgroundColor: #eee, }, }); export default App;要点提示示例中enableDynamicSizing{false}与显式声明snapPoints搭配保证 FlashList 的尺寸测量不被动态内容高度干扰estimatedItemSize是 FlashList 性能的关键参数应填列表中常规行高的近似值示例 43.3 为每行 padding/margin 相加所得提供后 FlashList 才能跳过首轮全量测量、直接复用估算的布局列表必须位于BottomSheet内部才能拿到手势上下文——见下文源码原理。五、源码原理它如何与 BottomSheet 手势联动BottomSheetFlashList之所以能听懂 bottom sheet 的拖拽关键在 src/components/bottomSheetScrollable/createBottomSheetScrollableComponent.tsx 这个工厂函数。从源码结构看所有BottomSheet*滚动组件都经由它生成其核心链路如下原生手势并联组件通过useContext(BottomSheetDraggableContext)取到 bottom sheet 的拖拽手势draggableGesture然后用Gesture.Native().simultaneousWithExternalGesture(draggableGesture)把滚动原生的 pan 手势与弹层拖拽手势声明为同时进行的关系源码 L88-L97。因此手指既可以在列表内部滚动也可以在列表顶部继续把整个 sheet 往下拖。滚动状态同步通过useScrollHandler捕获onScroll将列表的 contentOffset 写入共享值scrollableContentOffsetY同时由useAnimatedProps根据 bottom sheet 的滚动状态SCROLLABLE_STATE.UNLOCKED等实时切换decelerationRate与滚动指示器显隐源码 L77-L86实现滚动到底后继续拖拽弹层时截然不同的物理反馈。内容尺寸上报handleContentSizeChange通过setContentSize把内容高度回传供 bottom sheet 的动态尺寸dynamic sizing计算使用源码 L101-L109。滚动容器包装最终渲染由 ScrollableContainer.tsx 完成它把BottomSheetDraggableScrollable包在 FlashList 外层将手势上下文传递到列表内部。值得一提的还有其受控解构BottomSheetFlashListComponent会把 bottom sheet 专有的focusHook、scrollEventsHandlersHook、enableFooterMarginAdjustment从 props 中剥离仅将这些能力注入到内部替换的BottomSheetScrollView中其余 props 原样透传给 FlashList见 BottomSheetFlashList.tsx。六、实战进阶仿 Twitter 时间线的分页加载示例仓库示例 example/src/screens/integrations/flashlist/FlashListExample.tsx 提供了一个更贴近真实业务的数据流示例底部弹层内渲染推文时间线支持 25% / 50% / 90% 三档吸附并演示了 FlashList 的典型进阶能力onEndReached分页加载滚动到底部时延时 1s 再追加 10 条推文setTweets([...tweets, ...remainingTweets.current.splice(0, 10)])配合ListFooterComponent展示加载中的ActivityIndicator或没有更多推文的结束态ListEmptyComponent数据为空时展示欢迎引导视图viewabilityConfig配置waitForInteraction: true、itemVisiblePercentThreshold: 50、minimumViewTime: 1000用于内容可见性统计类场景ItemSeparatorComponent以StyleSheet.hairlineWidth的分隔线实现类 Twitter 的细分隔视觉estimatedItemSize{150}将推文卡片估算高度提前告知 FlashList显著降低长列表的初始渲染成本。同时示例还演示了expand()、collapse()、close()与snapToIndex()等实例方法的组合使用是阅读BottomSheetFlashList生产级用法的直接入口。七、常见问题抛错 You need to install FlashList first说明shopify/flash-list未安装或 Metro 解析失败请先执行yarn install shopify/flash-list并重启 Metro多滚动组件/React Navigation 场景下手势错乱为每个BottomSheetFlashList显式传入focusHook{useFocusEffect}让滚动 ref 的注册与焦点同步footer 遮挡列表末尾内容开启enableFooterMarginAdjustment让列表底部自动让出动画 footer 的高度。结语BottomSheetFlashList把 FlashList 的高性能列表渲染能力与 bottom sheet 的交互手势做成了开箱即用的组合安装shopify/flash-list后即可直接使用全部FlashListProps原样继承并额外获得focusHook、enableFooterMarginAdjustment、scrollEventsHandlersHook等 bottom sheet 专属能力。配合 website/docs/components/bottomsheetflashlist.md 与 example/src/screens/integrations/flashlist/FlashListExample.tsx你可以在几分钟内为 App 加入一个可拖拽、可吸附、可无限滚动的底部弹层列表。赞分享前端移动开发UI组件跨平台【免费下载链接】react-native-bottom-sheetA performant interactive bottom sheet with fully configurable options 项目地址https://gitcode.com/gh_mirrors/re/react-native-bottom-sheet点击查看免费下载相关推荐react-native-bottom-sheet 的 BottomSheetFlatList预集成 FlatList 与手势联动的深度指南react native bottom sheet 的 BottomSheetFlatList预集成 FlatList 与手势联动的深度指南 导读 Botto前端移动开发UI组件跨平台Pika Pack插件系统深度解析打造个性化npm构建流程Pika Pack插件系统深度解析打造个性化npm构建流程 Pika Pack是一款基于可组合插件的npm包构建工具它允许开发者通过灵活配置插件来定制自己的KrkrzExtract 怎么用新一代 krkrz 引擎 xp3 资源提取工具的完整上手记录KrkrzExtract 怎么用新一代 krkrz 引擎 xp3 资源提取工具的完整上手记录 如果你玩过用 krkrz 引擎TVP开发的 galgame前端移动开发UI组件跨平台上一篇DeFi 协议模板实战用 Solidity 实现 Governance 治理代币与 Flash Loan 闪电贷GitHub agents24 项目下一篇终极摄像头流媒体解决方案go2rtc让跨协议视频流转码变得如此简单创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

电机控制面试:Simulink仿真做到什么程度才不会被问崩 2026/9/25 3:44:51

电机控制面试:Simulink仿真做到什么程度才不会被问崩

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
NodeGui 中的 ColorDialogOption 枚举解析:颜色对话框选项的值、组合方式与底层实现 2026/9/25 3:44:51

NodeGui 中的 ColorDialogOption 枚举解析:颜色对话框选项的值、组合方式与底层实现

桌面应用跨平台 【免费下载链接】nodegui A library for building cross-platform native desktop applications with Node.js and CSS 🚀. React NodeGui : https://react.nodegui.org and Vue NodeGui: https://vue.nodegui.org 项目地址: https://git…

阅读更多 →
SQL Server SQL Assessment API 实战指南:从快速最佳实践评估到自定义规则集(sql-server-samples 仓库详解) 2026/9/25 3:44:51

SQL Server SQL Assessment API 实战指南:从快速最佳实践评估到自定义规则集(sql-server-samples 仓库详解)

示例工程数据库教程后端 【免费下载链接】sql-server-samples Azure Data SQL Samples - Official Microsoft GitHub Repository containing code samples for SQL Server, Azure SQL, Azure Synapse, and Azure SQL Edge 项目地址: https://gitcode.com/gh_mirrors…

阅读更多 →
OBJ模型贴图丢失的三大根源:路径、UV与材质绑定 2026/9/25 3:44:51

OBJ模型贴图丢失的三大根源:路径、UV与材质绑定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
大模型应用落地全指南:从选型到微调部署实践 2026/9/25 3:44:33

大模型应用落地全指南:从选型到微调部署实践

这两年谁要是还敢说自己没听过“大模型”三个字,大概是真的脱离科技圈了。从GPT刷屏到国内Qwen、DeepSeek接连开源,再到身边越来越多把大模型接进业务系统的案例,这个领域的更新速度已经快到“追都追不动”的程度。我做AI应用开发这些年&…

阅读更多 →
在 VoltAgent 中使用 Scaleway 生成式 AI:OpenAI 兼容模型路由完整配置指南 2026/9/25 3:44:33

在 VoltAgent 中使用 Scaleway 生成式 AI:OpenAI 兼容模型路由完整配置指南

人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆 【免费下载链接】voltagent AI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework 项目地址: https://gitcode.com/gh_mirrors/vo/voltagent 点击查看 免费下载 本…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉