Flutter + iOS 实战指南:教程视频 PiP + 退桌面(可复用模板)

这篇文章解决什么问题

目标不是"讲原理",而是给你一套以后能直接复用的方案,用来快速实现:

  1. Flutter 页面点击触发原生能力。
  2. iOS 启动隐藏视频播放器并进入 PiP。
  3. PiP 启动后主动退到桌面。
  4. App 回前台时,立即关闭 PiP,而不是只暂停。

这套方案适合沉淀成团队模板,也适合直接喂给 AI,让它一次产出高质量代码。


适用场景

  1. 引导用户添加小组件的教程悬浮窗。
  2. 退到桌面后继续播放短视频教学。
  3. 仅 iOS 需要

最小实现蓝图

调用链路固定为:

Flutter 点击事件

-> NativeWidgetUtil

-> Pigeon HostApi

-> iOS PiP Manager(AVPlayer + AVPictureInPictureController)

-> suspend 退桌面

建议文件分层:

  1. pigeon/native_widget_service.dart 定义接口。
  2. lib/pigeon/native_widget_service.dart / native_widget_util.dart Dart 调用封装。
  3. ios/Runner/pigeon/NativeWidgetAPI.swift 放完整 PiP 管理器。
  4. Android/OHOS 侧实现 no-op。

关键实现步骤

1) Pigeon 新增统一入口

dart 复制代码
@HostApi()
abstract class NativeWidgetService {
  void startWidgetTutorialPipAndExitDebug(String assetPath, bool loop, bool muted);
}

执行生成(按你项目脚本):

  1. ./pigeon.sh

2) Flutter 页面入口

页面标题点击触发:

dart 复制代码
void onTapTitle() {
  if (!GetPlatform.isIOS) {
    MyToastUtil.showToast('该测试入口仅 iOS 可用');
    return;
  }
  unawaited(_startWidgetTutorialPipAndExitDebug());
}

Future<void> _startWidgetTutorialPipAndExitDebug() async {
  try {
    await NativeWidgetUtil.startWidgetTutorialPipAndExitDebug(
      assetPath: 'assets/audios/widget_add_tutorial.mp4',
      loop: true,
      muted: false,
    );
  } catch (e) {
    printLog('启动小组件教程画中画失败: $e');
    MyToastUtil.showToast('画中画启动失败,请稍后重试');
  }
}

3) iOS PiP Manager 必做项

一个类统一管理以下对象,避免散点逻辑:

  1. AVPlayer
  2. AVPlayerLayer
  3. AVPictureInPictureController
  4. 前台通知监听
  5. cleanup 生命周期

启动流程关键点:

  1. 校验 AVPictureInPictureController.isPictureInPictureSupported()
  2. 通过 FlutterDartProject.lookupKey(forAsset:) 找到 MP4。
  3. 用隐藏容器挂 AVPlayerLayer
  4. startPictureInPicture(),并处理首帧 isPictureInPicturePossible 为 false 的延迟兜底。

4) "边退边出"时序

在 delegate 的 willStartPictureInPicture 就触发:

swift 复制代码
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))

didStartPictureInPicture 再兜底一次,外加防重复标记 hasRequestedSuspend

这样用户体感最好,不会出现"PiP 出来后等一会才退桌面"。


5) 前台关闭 PiP 的稳定方案(核心)

这部分决定成败。推荐固定策略:

  1. 同时监听 willEnterForegrounddidBecomeActive
  2. 前台阶段持续调用 stopPictureInPicture(),不要只 pause()
  3. 做短间隔重试(例如 0.12s * 12 次)。
  4. 多次 stop 仍失败时,断开 playerLayer.player = nil 后再 stop。
  5. 只在 didStop 回调或确认 isPictureInPictureActive == false 后 cleanup。

restoreUserInterfaceForPictureInPictureStopWithCompletionHandler 返回 true,可减少灰底等待态。


6) 必加日志(排障效率翻倍)

建议统一前缀,例如 小组件教程画中画,打印:

  1. 启动成功/失败。
  2. active / possible / retry
  3. willStart / didStart / willStop / didStop
  4. 前台兜底断链是否触发。

你会快速判断是:

  1. 系统没收到 stop。
  2. 回调没回来。
  3. cleanup 过早导致状态机断裂。

7) AI 一次生成高质量代码的提示词模板

把下面这段直接给 AI,成功率会高很多:

text 复制代码
请在 Flutter 项目中实现"教程视频 PiP + 退桌面"能力,要求:
1) 页面入口:历史页标题点击触发;
2) Flutter 仅调用 NativeWidgetUtil,不在页面内渲染视频;
3) 用 Pigeon 新增 HostApi:startWidgetTutorialPipAndExitDebug(String assetPath, bool loop, bool muted);
4) iOS 原生在 NativeWidgetAPI.swift 内新增独立管理器,使用 AVPlayer + AVPictureInPictureController;
5) 启动时序:willStartPictureInPicture 即触发 suspend,didStart 再兜底;
6) 回前台必须关闭 PiP,不是仅暂停:
   - 监听 willEnterForeground + didBecomeActive;
   - stopPictureInPicture 重试;
   - 必要时断开 playerLayer.player 再 stop;
   - 仅 didStop 或 inactive 后 cleanup;
7) Android/OHOS 实现 no-op;
8) 代码要包含中文注释,抽常量,提升可维护性;
9) 输出修改文件清单、关键 diff、验收步骤。

8) 验收清单(复制即测)

  1. iOS 真机点击入口后,出现 PiP 并退桌面。
  2. 回到前台时,PiP 在短时间内关闭,不只暂停。
  3. 不支持 PiP 的机型不崩溃,有错误提示。
  4. Android/OHOS 不受影响。
  5. flutter analyze 与 iOS 构建通过。

按这个模板实现这个功能,下次你或 AI 都能少走很多弯路。

感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

相关推荐
harder3212 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
maaath3 小时前
【maaath】Flutter for OpenHarmony 跨平台工程集成密码加密能力
flutter·华为·harmonyos
yeziyfx3 小时前
Flutter 纯色矩形
flutter
liulian09164 小时前
Flutter for OpenHarmony 混合开发实践:用户反馈功能的实现与适配
flutter·华为·学习方法·harmonyos
Hello__77775 小时前
开源鸿蒙 Flutter 实战|文章分类标签功能全流程实现
flutter·开源·harmonyos
xiaoyan20156 小时前
2026爆肝!Flutter3.41纯手撸微信聊天APP原生应用
android·flutter·dart
程序员老刘6 小时前
当全网都在喊“程序员要被AI取代了”,Flutter给了另一种答案
flutter·ai编程·客户端
国医中兴6 小时前
Flutter 三方库 nhost_graphql_adapter 的鸿蒙化适配指南 - 云端数据实时对齐、GraphQL 架构实战、鸿蒙级全栈交互专家
flutter·harmonyos·graphql
for_ever_love__7 小时前
UI学习:UITableView的基本操作及折叠cell
学习·ui·ios
IntMainJhy9 小时前
Flutter 三方库 get_it + flutter_bloc 的鸿蒙化适配与实战指南
flutter·华为·harmonyos