
web-to-app 长按菜单六种上下文菜单样式的配置、交互与源码实现剖析【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app在 web-to-app 中将网页包装成 App 后长按页面中的图片、视频或链接时弹出的上下文菜单保存图片、复制链接、下载视频、在浏览器中打开等是可定制的核心体验之一。本文围绕 编辑通用配置中的“长按菜单”文档 展开完整覆盖longPressMenuStyle的全部六种取值及其与longPressMenuEnabled的联动规则并结合LongPressMenuCard设置界面、WebViewLongPressMenu运行时分发逻辑与LongPressHandler事件识别链的源码讲解每种样式的交互形态、默认值、兜底策略与菜单项差异帮助你在配置导出型 App 时精确控制长按行为。配置入口长按菜单卡片长按菜单的设置位于“编辑通用配置”编辑器中的长按菜单卡片英文文档对应 Long-press Menu 一节中文入口见 编辑通用配置。卡片由 LongPressMenuCard 实现包含两层控件总开关WtaToggleRow直接控制长按菜单是否启用。源码中的联动逻辑非常直观——// app/src/main/java/com/webtoapp/ui/screens/CreateAppWebViewCards.kt (L88-L93) onCheckedChange { checked - onStyleChange( if (checked) LongPressMenuStyle.FULL else LongPressMenuStyle.DISABLED ) }即打开开关时默认落到FULL样式关闭时回到DISABLED。样式选择区FlowRowWtaChip芯片仅在开关打开时以展开动画AnimatedVisibility呈现提供FULL、SIMPLE、IOS、FLOATING、CONTEXT五个可选项每项带图标与多语言描述文案文案定义于 Strings.kt支持中、英、阿、葡、西、法、德、俄、日、韩十种语言。六个样式选项longPressMenuStyle样式枚举定义在 WebApp.ktenum class LongPressMenuStyle { DISABLED, SIMPLE, FULL, IOS, FLOATING, CONTEXT }各样式的官方界面文案与源码级交互形态如下表描述文案摘自 Strings.kt 的中文资源样式界面名称官方描述交互形态源码实现DISABLED—关闭无长按菜单同时禁用直接调用onDismiss()不显示任何 UIFULL完整显示所有可用操作ModalBottomSheet底部弹窗含图片预览/标题区 全部操作项SIMPLE精简仅显示保存图片和复制链接ModalBottomSheet每个资源类型只保留最核心的 1~2 个操作IOSiOS 风格毛玻璃背景类似 iPhone 体验全屏半透明遮罩 居中圆角卡片弹簧缩放/淡入动画FLOATING悬浮气泡在点击位置显示圆形气泡菜单以触摸点为圆心向四周径向展开彩色气泡按钮CONTEXT右键菜单类似桌面端右键菜单紧凑高效在触摸点弹出 200dp 宽的紧凑列表式 Popup运行时分发样式如何决定菜单 UI样式到 UI 的映射集中在 WebViewLongPressMenu.kt这是一个when (menuStyle)的纯分发函数同时把四个动作回调onCopyLink/onSaveImage/onDownloadVideo/onOpenInBrowser绑定到 LongPressHandler 的真实能力上// app/src/main/java/com/webtoapp/ui/webview/WebViewLongPressMenu.kt (L44-L100节选) when (menuStyle) { LongPressMenuStyle.SIMPLE - SimpleLongPressMenuSheet(...) LongPressMenuStyle.FULL - LongPressMenuSheet(...) LongPressMenuStyle.IOS - IosStyleLongPressMenu(...) LongPressMenuStyle.FLOATING - FloatingBubbleLongPressMenu(touchX touchX, touchY touchY, ...) LongPressMenuStyle.CONTEXT - ContextMenuLongPressMenu(touchX touchX, touchY touchY, ...) LongPressMenuStyle.DISABLED - onDismiss() // 不显示任何菜单 }调用点位于 WebViewActivity.kt这里体现了与配置默认值不同的运行时兜底策略WebViewLongPressMenu( menuStyle webApp?.webViewConfig?.longPressMenuStyle ?: LongPressMenuStyle.FULL, ... )即当webViewConfig缺失时样式兜底为FULL而长按事件的入口判断同样以longPressMenuEnabled为准且缺失时按true处理见 WebViewActivity.kt 与 L2798。另外在 Shell 模式下 ShellWebViewConfig.kt 用valueOf解析持久化的样式字符串解析失败时同样回落到FULL。菜单项差异FULL / SIMPLE / FLOATING 各自提供哪些操作长按识别的结果类型定义在 LongPressHandler.ktsealed class LongPressResult { data class Image(val url: String) : LongPressResult() data class Video(val url: String) : LongPressResult() data class Link(val url: String, val title: String? null) : LongPressResult() data class ImageLink(val imageUrl: String, val linkUrl: String) : LongPressResult() object Text : LongPressResult() object None : LongPressResult() }基于该结果集各样式在 LongPressMenu.kt 中的菜单项构成存在明确差异FULLLongPressMenuSheet图片预览图blob:源不渲染预览 图片地址截断展示 「保存图片」「复制图片链接」视频视频图标 地址 「下载视频」「复制视频链接」链接标题 地址 「复制链接」「在浏览器中打开」图片链接ImageLink分组展示「图片」保存图片/复制图片链接与「链接」复制链接地址/在浏览器中打开两组操作。SIMPLESimpleLongPressMenuSheet精简版图片保留「保存图片」「复制图片链接」但视频与链接一律退化为只读信息头 单个「复制链接」按钮不提供下载视频与在浏览器中打开。FLOATING/CONTEXT菜单项与FULL相同FLOATING用彩色气泡按钮 悬浮标签CONTEXT用带图标的紧凑行ImageLink场景中间插入分隔线区分图片组与链接组区别仅在呈现形态。对于Text/None类型结果各样式统一走else - onDismiss()分支即纯文本长按不弹出自定义菜单保留系统默认行为。IOS样式IosStyleLongPressMenu使用全屏 40% 黑色遮罩 居中 300dp 卡片卡片带bouncySpring缩放与settleSpring淡入动画链接标题区采用浅色/深色自适应背景整体还原 iPhone 的长按卡片质感FLOATING样式则以触摸坐标为原点按角度均分排布 52dp 圆形气泡中心带关闭按钮气泡下方在展开进度超过 0.5 时浮现文字标签。longPressMenuEnabled 与样式的联动规则文档中的核心规则是选择DISABLED以外的任意样式都会启用长按菜单longPressMenuEnabled。该规则在源码中有两处直接印证设置界面保存时CreateAppScreen.ktlongPressMenuEnabled it ! LongPressMenuStyle.DISABLED,设置卡片自身CreateAppWebViewCards.ktval enabled style ! LongPressMenuStyle.DISABLED也就是说longPressMenuEnabled并非独立持久化的“第二开关”而是由样式推导出来的派生状态两者必须保持一致样式为DISABLED时开关自动关闭反之为开启。数据模型中两个字段相邻声明于 WebApp.kt且新建配置的初始值均为“禁用”longPressMenuEnabled false、longPressMenuStyle LongPressMenuStyle.DISABLED因此不主动打开开关的 App 默认没有自定义长按菜单。底层识别链长按如何被识别为图片/视频/链接菜单展示只是结果识别逻辑在 LongPressHandler 中。其injectLongPressEnhancer会向页面注入一段 JS 增强脚本核心策略是只拦截图片相关元素的contextmenu事件不干扰普通 touch 事件——从源码注释可见这样做是为了避免破坏网页自身的点击逻辑例如阅读器的中央点击设置。判定“图片相关”的规则包括向上追溯最多 10 层父节点命中IMG/CANVAS标签、计算样式中含url(...)的背景图或命中特定轮播/图片容器的类名如note-image、swiper、carousel、image。三个核心动作同样由LongPressHandler提供分别位于 copyToClipboard、saveImage 与 downloadVideo保存/下载均以回调(Boolean, String)返回结果由WebViewLongPressMenu统一以 Toast 呈现。视频类型识别依赖后缀集合.mp4、.webm、.ogg、.mov、.avi、.mkv、.m3u8该常量定义于 LongPressHandler.kt。小结配置建议与相关源码索引需要完整下载/打开能力的场景视频站、图床选FULL追求克制体验选SIMPLE偏好桌面交互习惯选CONTEXT追求动效表现选IOS或FLOATING。DISABLED与longPressMenuEnabled false语义等价配置工具只需维护样式字段即可保证开关一致。注意运行时兜底webViewConfig缺失时长按事件按启用处理: true样式按FULL渲染因此“未配置”不等于“禁用”需要明确禁用时应显式保存DISABLED。相关源码索引样式枚举与默认值WebApp.kt、WebApp.kt设置卡片 UICreateAppWebViewCards.kt样式分发WebViewLongPressMenu.kt五种菜单 UI 实现LongPressMenu.kt长按识别与动作实现LongPressHandler.kt多语言样式描述Strings.kt【免费下载链接】web-to-appThe most full featured web-to-app toolkit on Android, a complete APK workshop that runs entirely on your phone项目地址: https://gitcode.com/GitHub_Trending/web/web-to-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考