Flutter如何实现flutter_in_app_pip功能

在Flutter中如何实现类似flutter_in_app_pip(画中画)的功能?目前官方似乎没有提供直接支持,有没有成熟的第三方插件或实现方案?主要想实现视频播放时能缩小为浮动窗口并保持在最前端显示的功能,最好能兼容iOS和Android平台。需要具体的代码实现思路或推荐可用的插件。

2 回复

Flutter实现画中画功能可通过flutter_inappwebview插件或原生平台通道。步骤:

  1. 添加插件依赖。
  2. AndroidManifest.xml中配置画中画权限。
  3. 使用PictureInPicture接口启动/管理画中画模式。 适用于视频播放等场景。

更多关于Flutter如何实现flutter_in_app_pip功能的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Flutter 中实现画中画(Picture-in-Picture, PiP)功能,通常需要使用 flutter_inappwebview 插件(适用于 WebView 内容)或原生平台通道(适用于自定义内容)。以下是实现步骤:

1. 使用 flutter_inappwebview 插件(适用于 Web 视频)

适用于在 WebView 中播放视频时启用 PiP。

步骤:

  1. 添加依赖

    dependencies:
      flutter_inappwebview: ^6.0.0
    

    运行 flutter pub get

  2. 配置原生平台

    • Android
      • AndroidManifest.xml 中为 Activity 添加属性:
        <activity
          android:name=".MainActivity"
          android:supportsPictureInPicture="true"
          android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
          android:launchMode="singleTop"
          android:resizeableActivity="true" />
        
      - 设置最小宽度/高度(可选):
        ```xml
        <meta-data
          android:name="android.min_aspect"
          android:value="1.5" />
      
    • iOS
      • Info.plist 中启用音频后台模式(若需音频):
        <key>UIBackgroundModes</key>
        <array>
          <string>audio</string>
        </array>
        
      • 为项目启用 “Audio, AirPlay, and Picture in Picture” 能力(Xcode 中设置)。
  3. 在 Flutter 中使用

    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    class PiPWebView extends StatefulWidget {
      @override
      _PiPWebViewState createState() => _PiPWebViewState();
    }
    
    class _PiPWebViewState extends State<PiPWebView> {
      late InAppWebViewController webViewController;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: InAppWebView(
            initialUrlRequest: URLRequest(url: Uri.parse("https://example.com/video")),
            onWebViewCreated: (controller) {
              webViewController = controller;
            },
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              // 触发 PiP 模式(仅 Android 支持此方法)
              webViewController.enterPipMode();
            },
            child: Icon(Icons.picture_in_picture),
          ),
        );
      }
    }
    
    • 注意enterPipMode() 目前主要适用于 Android。iOS 的 PiP 通常由系统自动触发(如全屏视频播放时)。

2. 使用平台通道实现自定义 PiP

若需非 WebView 内容(如自定义播放器)的 PiP,需通过平台通道调用原生代码。

步骤:

  1. 在 Flutter 中定义方法通道

    import 'package:flutter/services.dart';
    
    class PiPManager {
      static const platform = MethodChannel('com.example/pip');
    
      static Future<void> enterPipMode() async {
        try {
          await platform.invokeMethod('enterPipMode');
        } on PlatformException catch (e) {
          print("Failed: ${e.message}");
        }
      }
    }
    
  2. Android 原生实现

    • MainActivity.kt 中:
      import android.app.PictureInPictureParams
      import android.util.Rational
      import io.flutter.embedding.android.FlutterActivity
      import io.flutter.embedding.engine.FlutterEngine
      import io.flutter.plugin.common.MethodChannel
      
      class MainActivity : FlutterActivity() {
        private val CHANNEL = "com.example/pip"
      
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
          super.configureFlutterEngine(flutterEngine)
          MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "enterPipMode") {
              enterPipMode()
              result.success(null)
            } else {
              result.notImplemented()
            }
          }
        }
      
        private fun enterPipMode() {
          if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val params = PictureInPictureParams.Builder()
              .setAspectRatio(Rational(16, 9))
              .build()
            enterPictureInPictureMode(params)
          }
        }
      }
      
  3. iOS 原生实现

    • 使用 AVPictureInPictureController(仅支持 AVPlayerViewController),需在 Swift 中配置。

注意事项:

  • 兼容性:PiP 需要 Android 8.0(API 26)及以上,iOS 14 及以上。
  • 内容限制:Android 上 PiP 仅适用于视频播放或导航等场景。
  • 测试:在真机上测试,模拟器可能不支持 PiP。

根据需求选择合适方案。WebView 方案更简单,自定义方案需更多原生开发。

回到顶部