Flutter展示演示显示屏插件presentation_displays的使用
Flutter展示演示显示屏插件presentation_displays的使用
插件简介
presentation_displays
是一个支持iOS和Android平台的Flutter插件,允许应用程序在两个屏幕上运行。它通过创建Flutter代码中的Widget,并将其传递给原生代码侧转换为FlutterEngine
并保存到FlutterEngineCache
中以供后续使用。然后定义需要显示的Display(通过displayId),从FlutterEngineCache
获取FlutterEngine
并将其传输到Dialog Presentation
作为View进行显示。
主要功能:
- 获取连接设备列表及其信息。
- 将数据从主屏幕传输到次级屏幕。
- 在次级屏幕上接收数据。
- 设置新的入口点用于初始化次级屏幕。
示例代码详解
1. 配置路由生成函数
Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => const DisplayManagerScreen());
case 'presentation':
return MaterialPageRoute(builder: (_) => const SecondaryScreen());
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}')),
));
}
}
此函数根据路由名称返回相应的页面。
2. 初始化应用与次级屏幕入口
void main() {
debugPrint('first main');
runApp(const MyApp());
}
@pragma('vm:entry-point')
void secondaryDisplayMain() {
debugPrint('second main');
runApp(const MySecondApp());
}
这里定义了两个入口点:一个是主应用程序的入口,另一个是专门用于次级屏幕的应用程序入口。
3. 定义主应用与次级应用
class MySecondApp extends StatelessWidget {
const MySecondApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
onGenerateRoute: generateRoute,
initialRoute: 'presentation',
);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
onGenerateRoute: generateRoute,
initialRoute: '/',
);
}
}
这两个类分别定义了主应用和次级应用的布局结构。
4. 创建按钮组件
class Button extends StatelessWidget {
final String title;
final VoidCallback? onPressed;
const Button({Key? key, required this.title, this.onPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(4.0),
child: ElevatedButton(
onPressed: onPressed,
child: Text(
title,
style: const TextStyle(fontSize: 25),
),
),
);
}
}
这是一个简单的按钮组件,可以方便地复用。
5. 显示管理界面
class DisplayManagerScreen extends StatefulWidget {
const DisplayManagerScreen({Key? key}) : super(key: key);
@override
_DisplayManagerScreenState createState() => _DisplayManagerScreenState();
}
class _DisplayManagerScreenState extends State<DisplayManagerScreen> {
// ... 省略部分代码 ...
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_getDisplays(),
_showPresentation(),
_hidePresentation(),
_transferData(),
_getDisplayeById(),
_getDisplayByIndex(),
],
),
),
),
);
}
// ... 省略部分代码 ...
}
该界面提供了几个操作按钮,包括获取所有显示设备、显示/隐藏次级屏幕、传输数据等。
6. 次级屏幕UI
class SecondaryScreen extends StatefulWidget {
const SecondaryScreen({Key? key}) : super(key: key);
@override
_SecondaryScreenState createState() => _SecondaryScreenState();
}
class _SecondaryScreenState extends State<SecondaryScreen> {
String value = "init";
@override
Widget build(BuildContext context) {
return Scaffold(
body: SecondaryDisplay(
callback: (dynamic argument) {
setState(() {
value = argument;
});
},
child: Container(
color: Colors.white,
child: Center(
child: Text(value),
),
),
));
}
}
这是次级屏幕上显示的内容,其中包含了一个接收来自主屏幕的数据并更新显示内容的功能。
注意事项
- 对于iOS平台,可能需要在AppDelegate中添加一些特定的代码来确保正常工作。
- 测试时,请确保设备支持USB C 3.0及以上版本或HDMI输出。
- 当前版本已支持Android发布构建,并且示例应用程序已经过测试,可以在Android平板和iOS平板上正常使用。
通过以上步骤和提供的完整示例代码,您可以轻松地在项目中集成presentation_displays
插件,实现多屏展示功能。
更多关于Flutter展示演示显示屏插件presentation_displays的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter展示演示显示屏插件presentation_displays的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用presentation_displays
插件来展示演示显示屏的示例代码。这个插件允许你在连接到主显示设备的其他显示设备上展示内容,例如投影仪或外部显示器。
首先,确保你已经在pubspec.yaml
文件中添加了presentation_displays
插件的依赖:
dependencies:
flutter:
sdk: flutter
presentation_displays: ^0.x.x # 请使用最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,是一个简单的示例代码,展示如何使用presentation_displays
插件:
import 'package:flutter/material.dart';
import 'package:presentation_displays/presentation_displays.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Presentation Displays Example'),
),
body: PresentationScreen(),
),
);
}
}
class PresentationScreen extends StatefulWidget {
@override
_PresentationScreenState createState() => _PresentationScreenState();
}
class _PresentationScreenState extends State<PresentationScreen> {
PresentationDisplay? _currentDisplay;
PresentationDisplayConnection? _connection;
bool _isPresenting = false;
@override
void initState() {
super.initState();
_initializePresentationDisplays();
}
Future<void> _initializePresentationDisplays() async {
PresentationDisplayList displays = await PresentationDisplayList.requestAvailability();
if (displays.availableDisplays.isNotEmpty) {
setState(() {
_currentDisplay = displays.availableDisplays.first;
});
} else {
print('No available displays.');
}
}
Future<void> _startPresentation() async {
if (_currentDisplay == null) return;
_connection = await _currentDisplay!.requestConnection();
if (_connection != null) {
setState(() {
_isPresenting = true;
});
// 创建一个新的Widget来在演示显示屏上显示
_connection!.startPresentation(
context,
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Presentation Display'),
),
body: Center(
child: Text('This is displayed on the presentation display!'),
),
),
),
);
}
}
Future<void> _stopPresentation() async {
if (_connection != null) {
await _connection!.close();
setState(() {
_isPresenting = false;
_connection = null;
});
}
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Current Display: ${_currentDisplay?.displayName ?? 'None'}'),
SizedBox(height: 20),
ElevatedButton(
onPressed: _isPresenting ? _stopPresentation : _startPresentation,
child: Text(_isPresenting ? 'Stop Presentation' : 'Start Presentation'),
),
],
),
);
}
@override
void dispose() {
_stopPresentation();
super.dispose();
}
}
代码说明
- 依赖安装:在
pubspec.yaml
中添加presentation_displays
插件依赖。 - 初始化:在
initState
方法中调用_initializePresentationDisplays
来请求可用的演示显示屏列表。 - 显示列表:如果检测到可用的演示显示屏,将其设置为
_currentDisplay
。 - 开始演示:
_startPresentation
方法请求与当前显示屏的连接,并在连接成功后启动一个新的Widget树进行显示。 - 停止演示:
_stopPresentation
方法关闭与演示显示屏的连接。 - 按钮控制:通过按钮控制开始和停止演示。
请确保在实际使用时处理错误和异常情况,例如检查_connection
是否成功建立,以及处理连接失败的情况。这个示例提供了一个基本的框架,你可以根据需要进行扩展和修改。