SuperAPI AI 工具集

fullscreen-video-gesture-overlay

编程与开发

查看项目

更新于 10-17 16:15

技能介绍

用途

该资料面向使用 Kotlin 与 Jetpack Compose 开发全屏视频播放页的开发者,给出一套手势层与控件层的组合结构及配套的排错清单,帮助避免点击区域失效、计时器重置错误、进度条回弹、画中画误触等常见问题。

主要能力与结构

全屏视频页被组织为同一个容器内的三个同级层,顺序固定:

  1. 视频画面层 VideoSurface,始终存在;
  2. 手势层,由两个 weight(1f) 的 SeekZone 组成,铺满整个画面,中间不留死区,保证每次点击都落在某个区域内;
  3. 控件层,用 Crossfade(chromeVisible) 控制显隐。隐藏时控件不参与组合,点击会穿透到下方手势层;显示时控件的按钮位于最上层,自行接收点击。

画中画模式(!isInPipMode)下手势层和控件层都不渲染,只有视频画面层保留,避免在缩略窗口内误触。

使用方式与关键实现要点

资料以代码片段说明实现方式,主要涉及:

  • 双击快进/快退与单击切换控件:每个手势区都要同时配置 onTap 与 onDoubleTap。若某个区只有双击而没有单击,该半屏点击就不会切换控件。
  • 点击反馈:detectTapGestures 本身不提供按压反馈,需手动通过 interactionSource 与 ripple() 驱动涟漪;释放时须使用与按下相同的 PressInteraction.Press 实例,否则指示不会清除;emit 是挂起函数,需要协程作用域;涟漪受修饰符链中 clip 约束,因此对区域内侧圆角裁剪才能呈现圆角半屏效果。
  • 自动隐藏计时器:使用 LaunchedEffect,以控件可见性和拖动状态作为键。以可见性为键可在每次切换时重新计时;以拖动状态为键可在拖动开始时取消、结束时重新启动,从而给用户完整窗口期。新增需要保持控件显示的行为时,应作为新的键加入,而非在函数体内加分支。
  • 进度条拖动:拖动期间用 isSliding 标志阻止播放器位置更新覆盖拖动值,在 onValueChange 中置位、onValueChangeFinished 中清除并派发一次跳转,避免每帧跳转。
  • 跳转命令统一:手势与按钮应派发同一个引擎自带的前进/后退命令,而非在 UI 层计算“当前位置 ± N”;旁边标注的步长需要与引擎配置一致。
  • 画中画状态:须以可触发重组的 Compose 状态读取,不能在普通变量中采样一次;有模式回调的平台订阅回调,没有的平台用常量 false。
  • 退出全屏恢复:进入全屏通常涉及锁定方向、隐藏系统栏、保持屏幕常亮,退出时需全部还原;保存原始方向必须在强制横屏之前;并检查恢复逻辑只写一次,避免 when 分支成为死代码。

验证方法

资料给出 grep 命令核对代码:

  • grep -rn --include="*.kt" "onDoubleTap" . 每个跳转区应各有一处;
  • grep -rn --include="*.kt" -B 8 "delay(" . | grep "LaunchedEffect" 每个计时器一处,并建议加大上下文行数以覆盖位于 else 分支的 delay;
  • grep -rn --include="*.kt" "PressInteraction.Press(" . 每处都须绑定局部变量并在下方用同一实例释放;
  • grep -rn --include="*.kt" "rememberIsInPipMode\|isInPictureInPictureMode" . 一处声明、每平台一份实现、每个绘制控件覆盖视频的页面一处读取。

手动验证顺序:点击右半屏应出现控件;双击左右半屏应跳转并出现以手指为中心的淡出涟漪;开始拖动并静止超过自动隐藏时长,控件应保持,松开后应再保持一个完整窗口期;缩为浮窗后应无控件、无手势,恢复后正常。最后离开页面,确认设备方向与系统栏恢复原状。

适用场景与限制

适用于基于 Compose 实现全屏视频播放交互的 Android 开发者,可作为实现与代码审查的参考。资料未提供安装方式、依赖版本、运行环境要求、发布形式或收费信息;代码片段由资料作者标注为“adapted”,使用前需结合自身项目调整。