ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Galeria Android 实现全解:3 个 Kotlin 核心模块如何搞定 Kotlin 桥接与 Edge-to-Edge 图片查看器

Galeria Android 实现全解:3 个 Kotlin 核心模块如何搞定 Kotlin 桥接与 Edge-to-Edge 图片查看器 Galeria Android 实现全解3 个 Kotlin 核心模块如何搞定 Kotlin 桥接与 Edge-to-Edge 图片查看器【免费下载链接】galeriaThe React (Native) Image Viewer. 项目地址: https://gitcode.com/gh_mirrors/ga/galeriaGaleria 图片查看器是一个面向 React Native 的 ReactNative图像查看器组件库 。本文带你拆解它的Android 端实现通过Expo Module 的 Kotlin 桥接、继承ImageViewerDialogFragment的全屏对话框以及一套Edge-to-Edge 边到边适配方案仅用约 300 行 Kotlin 代码就让图片查看体验无限接近原生。一、架构总览Android 端 6 个文件各管什么Galeria 在 Android 上的代码全部位于android/src/main/目录下职责划分非常清晰文件职责GaleriaModule.ktExpo Module 注册声明 Props 与事件GaleriaView.kt原生视图容器布局、点击、事件分发、图片加载EdgeToEdgeImageViewerDialogFragment.kt继承原生图片查看器对话框负责 Edge-to-Edge 适配styles.xml全屏透明 Dialog 主题GaleriaView.android.tsxTypeScript 侧原生视图桥接AndroidManifest.xml几乎为空——无需任何额外权限数据流向可以概括为一条流水线JS 传入 urls / theme / index ↓ Expo Module 桥接Props GaleriaViewViewGroup记录子 ImageView 的位置 ↓ 用户点击 EdgeToEdgeImageViewerDialogFragment 全屏弹出 ↓ 滑动 / 关闭 onIndexChange / onDismiss 事件回传 JS一个有趣的细节整个AndroidManifest.xml只有一个空的manifest标签。因为查看器以DialogFragment形式呈现不需要注册新的 Activity更不需要任何权限声明——这是它对宿主应用零侵入的关键。二、Kotlin 桥接Expo Module 如何打通 JS 与原生1. ModuleDefinition 声明 Props 与事件GaleriaModule.kt 使用 Expo Module API 的ModuleDefinition把模块注册为 JS 可见的名字Galeria并通过View(GaleriaView::class)声明它可用作原生视图7 个 Propstheme、urls、index、disableHiddenOriginalImage、edgeToEdge、transitionOffsetY、transitionOffsetX每个 Prop 本质上就是一个往GaleriaView上赋值的 setter3 个 EventsonIndexChange切换图片、onLongPress长按缩略图、onDismiss查看器关闭。2. TypeScript 侧一行注册原生视图GaleriaView.android.tsx 中requireNativeView(Galeria)一步拿到原生视图组件。随后它会做两件值得注意的事通过react-native-is-edge-to-edge的isEdgeToEdge()自动探测应用是否已启用边到边模式与业务传入的edgeToEdgeprop 合并后下发给原生GaleriaView.android.tsx把数字形式的本地资源 ID 用Image.resolveAssetSource解析成真实 URI与远程 URL 统一成字符串数组传给原生。JS 与 Kotlin 之间的约定最终汇总在 Galeria.types.ts 的GaleriaViewProps接口里——Props 与事件类型一一对应方便 TypeScript 做静态检查。三、DialogFragment 弹出机制点击缩略图到全屏的完整链路1. 从 onLayout 开始偷看每个 ImageViewGaleriaView继承自ViewGroup。在 GaleriaView.kt 中它重写了onLayout并调用setupImageViewer递归遍历子视图只要是ImageView就给它挂上点击监听遇到嵌套ViewGroup则继续递归——所以哪怕图片被包在 FlatList / FlashList 的单元格里也能被捕获。2. 伪造起始视图实现无缝共享元素过渡setupImageViewer 会构建底层图片查看器ImageViewerBuilder来自 Android 端开源库 imageviewer。其中fakeStartView是一个巧妙的技巧复制缩略图的宽高与屏幕坐标生成一个不可见的ImageView作为过渡动画的起点点击放大时图片就像从缩略图原地生长一样弹出视觉上完全没有割裂感。3. 三个事件回传 JSonIndexChange由 CustomViewerCallback 在onPageSelected时通过 Expo 的EventDispatcher发出携带currentIndexonLongPress挂在缩略图的长按监听上在查看器打开之前触发onDismiss由对话框关闭时回调见下节。还有个细节查看器打开的瞬间CustomViewerCallback.onInit会以 180ms 动画把原缩略图淡出关闭后再延迟 230ms 恢复——避免过渡期间出现双图叠影。四、Edge-to-Edge 边到边适配让图片真正铺满全屏现代 Android 系统要求应用内容延伸到状态栏与导航栏之下图片查看器若适配不好图片上下就会露出一条刺眼的色带。Galeria 用三层组合拳解决第 1 层全屏透明 Dialog 主题。styles.xml 定义了Theme.FullScreenDialog无标题、不浮动、窗口背景透明且状态栏与导航栏颜色全部设为android:color/transparent让内容真正延伸到屏幕边缘。第 2 层DialogFragment 重写窗口行为。EdgeToEdgeImageViewerDialogFragment.kt 在onCreateDialog中做两件事调用WindowCompat.setDecorFitsSystemWindows(window, false)关闭系统窗口的自动 inset让内容绘入系统栏区域用WindowInsetsControllerCompat根据themedark / light设置状态栏与导航栏文字图标的明暗保证亮色主题下图标依然清晰可见。它还有一个降级逻辑isAppearanceLightSystemBars为null即未启用 edgeToEdge时直接回退到父类的默认对话框兼容所有应用形态。第 3 层过渡偏移量补偿。GaleriaView.kt 的setupConfig中若未显式传入transitionOffsetY则 edge-to-edge 模式下偏移为 0图片本就顶到屏幕顶端否则自动补上状态栏高度——保证缩放过渡动画的起点像素级对齐。状态栏高度则通过反射系统资源status_bar_height获取getStatusBarHeight。关闭回调无论怎么关JS 都能收到通知对话框的 onDismiss 被重写为先走父类逻辑、再通知 JS。这意味着不管用户是下滑关闭、按系统返回键还是外部调用dismiss()对应viewModel.dismiss()onDismiss事件都一定会回传——业务侧可以可靠地同步状态。五、源码清单与延伸阅读想了解去看桥接的完整声明GaleriaModule.kt事件分发与图片加载GaleriaView.ktEventDispatcher声明、SimpleImageLoaderGlide 加载边到边窗口适配EdgeToEdgeImageViewerDialogFragment.ktJS 端桥接GaleriaView.android.tsx全局配置声明expo-module.config.json实际用法演示example/app/photos.tsx、example/app/list.tsx、example/app/masonry.tsx小结Galeria 的 Android 实现展示了 React Native 原生模块的三种典型能力——用Expo Module 的 Kotlin 桥接声明 Props/Events、用继承原生 DialogFragment复用成熟的图片查看器并注入全屏主题、用窗口 inset 控制 偏移补偿完成 Edge-to-Edge 适配。三层各司其职、互不耦合这也是它能在约 300 行 Kotlin 代码内交付接近原生体验的原因。【免费下载链接】galeriaThe React (Native) Image Viewer. 项目地址: https://gitcode.com/gh_mirrors/ga/galeria创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表