Flutter画中画功能插件fl_pip的使用
Flutter画中画功能插件fl_pip的使用
简介
fl_pip
是一个用于Flutter应用的插件,它允许开发者在iOS和Android平台上实现画中画(PiP, Picture-in-Picture)模式。通过这个插件,你可以显示Flutter的view,并且可以通过修改Flutter栈顶的view来展示任意UI。
然而,在iOS上存在一个问题:当应用处于后台时,Flutter UI可能会停止运行或直接黑屏。这可能是由于iOS冻结了应用程序导致的。目前还没有完美的解决方案,如果你有好的想法,请提交PR。
使用配置
iOS 配置
- 在
Signing & Capabilities
->Capability
中添加BackgroundModes
。 - 勾选
Audio, AirPlay, And Picture in Picture
。 - 修改
/ios/Runner/AppDelegate.swift
文件的内容如下:
import fl_pip
import Flutter
import UIKit
@main
@objc class AppDelegate: FlFlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func registerPlugin(_ registry: FlutterPluginRegistry) {
GeneratedPluginRegistrant.register(with: registry)
}
}
Android 配置
- 修改
android/app/src/main/${your package name}/MainActivity
继承FlPiPActivity
。 - 在
AndroidManifest.xml
文件中添加android:supportsPictureInPicture="true"
属性。
<application android:label="FlPiP">
<activity android:name=".MainActivity"
android:launchMode="singleTop"
android:supportsPictureInPicture="true" />
</application>
Kotlin 示例代码
class MainActivity : FlPiPActivity()
Java 示例代码
class MainActivity extends FlPiPActivity {
}
方法列表
以下是 fl_pip
插件提供的主要方法:
-
enable(): 开启画中画模式。
void enable() { FlPiP().enable( iosConfig: FlPiPiOSConfig(), androidConfig: FlPiPAndroidConfig( aspectRatio: const Rational.maxLandscape())); }
-
isAvailable(): 检查是否支持画中画模式。
bool isAvailable = await FlPiP().isAvailable;
-
isActive(): 获取当前画中画窗口的状态。
bool isActive = await FlPiP().isActive;
-
toggle(): 切换前后台(仅iOS支持切换到后台)。
void toggle() { FlPiP().toggle(); }
-
disable(): 退出画中画模式。
void disable() { FlPiP().disable(); }
示例代码
下面是一个完整的示例代码,展示了如何使用 fl_pip
插件创建一个带有计时器的应用程序,并启用画中画模式。
import 'package:flutter/material.dart';
import 'package:flutter_waya/flutter_waya.dart'; // Assuming this is a custom package for widgets like CountDown
void main() {
runApp(App(home: HomePage()));
}
/// mainName must be the same as the method name
@pragma('vm:entry-point')
void pipMain() {
runApp(ClipRRect(
borderRadius: BorderRadius.circular(12),
child: App(home: PiPHomePage())));
}
class App extends StatelessWidget {
const App({super.key, required this.home});
final Widget home;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: home);
}
}
class Timer extends StatelessWidget {
const Timer({super.key});
@override
Widget build(BuildContext context) => CountDown(
duration: const Duration(seconds: 500),
builder: (Duration duration, bool isRunning, VoidCallback startTiming) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 12),
child: Text('timer:${duration.inSeconds.toString()}'));
});
}
class Filled extends StatelessWidget {
const Filled({super.key, required this.text, this.onPressed});
final String text;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return FilledButton(
onPressed: onPressed, child: Text(text, textAlign: TextAlign.center));
}
}
// Example pages
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Home Page")),
body: Center(child: Text("This is the Home Page")),
);
}
}
class PiPHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("PiP Home Page")),
body: Center(child: Timer()),
);
}
}
在这个示例中:
pipMain
函数是必须的,如果使用enableWithEngine
方法。Timer
小部件展示了如何在画中画模式下显示一个倒计时。HomePage
和PiPHomePage
分别代表主页面和进入画中画模式后的页面。
希望这些信息能帮助你更好地理解和使用 fl_pip
插件。如果你有任何问题或需要进一步的帮助,请随时提问!
更多关于Flutter画中画功能插件fl_pip的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter画中画功能插件fl_pip的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中实现画中画(Picture-in-Picture,PiP)功能,你可以使用fl_pip
插件。这个插件可以帮助你在Android和iOS平台上实现画中画模式。以下是一个简单的示例,展示了如何使用fl_pip
插件在Flutter应用中实现画中画功能。
首先,确保你已经将fl_pip
插件添加到你的Flutter项目中。你可以在pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
fl_pip: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,是具体的代码实现。在这个例子中,我们将创建一个简单的Flutter应用,该应用包含一个视频播放器,并允许用户将视频播放切换到画中画模式。
1. 主应用代码(main.dart
)
import 'package:flutter/material.dart';
import 'package:fl_pip/fl_pip.dart';
import 'package:chewie/chewie.dart'; // 用于视频播放的插件,可以替换为你喜欢的视频播放器
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter PiP Example'),
),
body: Center(
child: PipProvider(
child: VideoPlayerScreen(),
),
),
),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
@override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
ChewieController? _chewieController;
@override
void initState() {
super.initState();
_chewieController = ChewieController(
source: ChewieSource(
mediaItem: MediaItem.network(
'https://www.w3schools.com/html/mov_bbb.mp4', // 替换为你的视频URL
mediaType: MediaType.video,
),
autoplay: true,
looping: true,
),
aspectRatio: ChewieAspectRatio.preserve,
autoPlay: true,
showControls: true,
materialProgressColors: ProgressColors(
playedColor: Colors.red,
handleColor: Colors.blue,
bufferedColor: Colors.grey.shade300,
),
// 其他ChewieController配置...
);
}
@override
Widget build(BuildContext context) {
return PipConsumer(
builder: (context, pipController) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Chewie(
controller: _chewieController!,
onEnterPictureInPicture: () {
pipController.enterPictureInPicture();
},
),
),
ElevatedButton(
onPressed: () {
pipController.enterPictureInPicture();
},
child: Text('Enter PiP Mode'),
),
],
);
},
);
}
@override
void dispose() {
_chewieController?.dispose();
super.dispose();
}
}
2. 配置Android权限(AndroidManifest.xml
)
在你的AndroidManifest.xml
文件中,确保添加了必要的权限以支持画中画模式:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
... >
<activity
...
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
...
</activity>
</application>
</manifest>
3. iOS配置(Info.plist
)
对于iOS,你需要确保你的Info.plist
文件中有适当的配置来支持画中画模式。通常,这不需要额外的键,但你需要确保你的应用支持后台音频播放,因为画中画通常伴随着音频播放。
注意事项
- 在实际项目中,你可能需要处理更多的状态管理和错误处理。
- 画中画模式在不同设备和操作系统版本上的行为可能有所不同,因此请务必进行充分的测试。
- 确保你的视频播放器插件支持画中画功能,或者根据需要进行自定义。
这个示例应该能帮助你快速上手在Flutter中使用fl_pip
插件实现画中画功能。