Flutter屏幕截图插件screenshooter的使用
Flutter屏幕截图插件screenshooter的使用
Automatically create screenshots of your flutter app.
工作原理
Screenshooter通过构建您的应用的一个特殊版本(使用不同的入口点)并在iOS模拟器上运行该版本来工作。此应用程序将执行您指定的操作,并在应截取屏幕截图时通知主机。这样可以确保屏幕截图与实际显示的内容完全一致,因为它实际上是模拟器的真实屏幕截图。
设置
要使您的应用与Screenshooter配合使用,需要完成两个步骤:
- 创建屏幕截图套件
- 创建配置文件
- (可选)添加框架配置
屏幕截图套件
屏幕截图套件是在客户端定义如何拍摄每个屏幕截图。创建一个应用程序的新入口点(默认为lib/screenshots.dart
),并添加一个ScreenshotSuite
实例并运行它。一个简单的套件可能如下所示:
// lib/screenshots.dart
import 'main.dart' as app;
void main() {
ScreenshotSuite(
name: 'default',
prepare: () async {
// 这将在其他一切之前执行。
// 您需要在这里启动真正的应用程序
app.main();
},
prepareLocale: (ScreenshotLocale locale) async {
// 如果您稍后在配置中指定了语言环境,则会为此每个语言环境调用此函数。
// 您可能希望在此处设置语言环境
setAppLocale(locale);
},
cleanupLocale: (ScreenshotLocale locale) async {
// 与prepareLocale相同,但显然在拍摄完所有语言环境的屏幕截图之后运行
clearCache();
},
cleanup: () {
removeData();
},
screenshots: [...]
).run();
}
屏幕截图由一个Screenshot
实例描述,这非常直观:
final screenshot = Screenshot(
// 唯一的屏幕截图名称
name: 'home',
// 调用准备后的延迟(例如等待图像加载)
delay: const Duration(seconds: 1),
prepare: () async {
await navigateToHome();
},
cleanup: () async {
// 执行一些清理操作
}
);
注意:所有方法都返回一个Future<void>
,在继续之前会等待其完成,因此您不必担心在事物准备好之前就拍摄屏幕截图。
屏幕截图配置
如果您想在运行时访问配置变量,可以使用ScreenshotConfiguration.fromEnv
。这是一个常量值,因此当用于if语句等时不会减慢您的应用程序速度。
如果要确定当前应用是否正在屏幕截图模式下运行,请使用ScreenshotConfiguration.fromEnv.isActive
。
如果要登录示例用户,您可以访问ScreenshotConfiguration.fromEnv.username
和ScreenshotConfiguration.fromEnv.password
,这些值将被传递给screenshooter。这些值来自CLI参数--username
和--password
,或者作为(推荐)回退从环境变量SCREENSHOOTER_USERNAME
和SCREENSHOOTER_PASSWORD
中获取。
配置文件
在设置好屏幕截图套件后,您需要指定如何运行它。尽管此时您可以直接使用命令行参数运行screenshooter,但建议使用配置文件。默认情况下将使用screenshooter.yaml
文件,如果没有找到则回退到pubspec.yaml
中的screenshooter
键(参见使用)。
使用配置文件还可以让您高效地为多个模拟器拍摄屏幕截图。
这是一个包含所有可能选项的配置文件示例 - 它们不是必需的:
# screenshooter.yaml
bundleId: com.example.app
# 这是每个屏幕截图的路径。占位符:
# - {locale} 将被替换为当前语言环境的语言标签(BCP47)
# - {name} 替换为`Screenshot`中指定的名称
# - {device} 替换为设备标识符(如在`devices`中指定)
path: screenshots/{locale}/{name}_{device}.png
# 要创建屏幕截图的所有语言环境(以BCP47格式用破折号分隔)。如果您省略了这个,
# 则只会拍摄一次屏幕截图,`path`中的{locale}将具有值`none`
locales:
- en-US
- de-DE
# 这是一个所有模拟器的列表。键是iOS模拟器的确切名称,值是使用的标识符
devices:
iPhone 14 Plus: iphone_65
iPhone 8 Plus: iphone_55
# 用作应用程序入口点的文件名
target: lib/screenshots.dart
使用
要在项目的根目录中运行screenshooter,请使用dart run screenshooter
。默认情况下,它将尝试查找screenshooter.yaml
文件以读取配置。如果没有找到,则会查找pubspec.yaml
中的screenshooter
键。
要加载另一个配置文件(例如,如果您有多个配置),请使用dart run screenshooter -f <您的config.yaml的名称>
。
使用dart run screenshooter --help
获取有关所有命令行参数的信息。
添加设备框架
Screenshooter还包括一个快速实现的屏幕截图框架。此步骤完全是可选的且独立于屏幕截图。使用dart run screenshooter:frame
在创建屏幕截图后运行此后处理。
除了添加设备框架外,此工具还可以使用titles
在框架顶部添加文本。生成的图像大小与原始屏幕截图相同。
这使用了meta设备框架,因为它们是免费提供的且相当新。对于图像处理,使用ImageMagick,因为它比纯Dart实现快得多。设备框架将自动下载到~/.cache/screenshooter-device-frames
目录中。为了找到好的frameSelectors
,您可以查看该目录。
注意:设备框架的下载链接不是静态的,必须从HTML页面解析。该工具应该能自动完成此操作,但如果失败了,您可以手动从这里下载存档并解压缩到~/.cache/screenshooter-device-frames
目录中,以便Meta Devices
子目录包含设备的文件夹。
注意事项
如何选择标题?
每个标题的关键字都会与屏幕截图的文件名进行比较。第一个包含该关键字的标题将被使用。
如何选择设备框架?
从screenshooter配置中使用的设备名称。在配置中,名称是devices
映射中的键。
配置
配置从screenshooter.frames.yaml
读取。如果此文件不存在,则从screenshooter.yaml
或pubspec.yaml
中的frames
键加载配置。
以下是一些可用选项,虽然并非所有都是必需的:
# 在每个屏幕截图顶部添加的文本。这些语言对应于`screenshooter.yaml`文件中`locales`部分中的语言。
# 文件名中第一个找到的该文件(例如"home","account")的键将被选中。
titles:
en-US:
home: 这是主页
account: 这是账户页
de-DE:
shop: 这是商店页面
account: 这是账户页面
# 在框架化屏幕截图后附加到文件名。
suffixFrame: _framed
# 在添加文本后附加到文件名。
suffixText: _text
# 选择使用哪些框架的标准。如果在目录层次结构的同一级别中有多个匹配项,则选择最短的一个。
frameSelectors:
- shadow
- white
- silver
- starlight
# 屏幕截图的背景颜色。可以是十六进制颜色或ImageMagick识别的颜色名称。
background: black
# 每边的填充百分比。相对于屏幕截图的宽度。
paddingPercent: 5
# 关于用于标题的字体设置。
font: ./fonts/OpenSans/OpenSans-Bold.ttf
fontSize: 75
fontColor: white
示例代码
以下是示例代码,演示了如何使用Screenshooter插件:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
final rootNavigatorKey = GlobalKey<NavigatorState>();
final appKey = GlobalKey<_MyAppState>();
Locale locale = const Locale('en', 'US');
List<Locale> locales = [
const Locale('en', 'US'),
const Locale('de', 'DE'),
];
void setLocale(Locale l) {
locale = l;
appKey.currentState?.restart();
}
class MyApp extends StatefulWidget {
MyApp() : super(key: appKey);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Key key = UniqueKey();
void restart() {
setState(() {
key = UniqueKey();
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Screenshooter Demo',
key: key,
navigatorKey: rootNavigatorKey,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: locale.countryCode == 'US' ? Colors.blue : Colors.green,
),
useMaterial3: true,
),
routes: {
'/': (context) => const CustomPage(
title: 'Home Page',
isHome: true,
),
'/other': (context) => const CustomPage(
title: 'Other Page',
isHome: false,
),
},
);
}
}
class CustomPage extends StatelessWidget {
final String title;
final bool isHome;
const CustomPage({
super.key,
required this.title,
required this.isHome,
});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Locale: $locale',
style: Theme.of(context).textTheme.titleLarge,
),
TextButton(
onPressed: () {
setLocale(locales.firstWhere((element) => element != locale));
},
child: Text(
'Switch to ${locales.firstWhere((element) => element != locale)}',
),
),
if (isHome)
ElevatedButton(
onPressed: () {
rootNavigatorKey.currentState!.pushNamed('/other');
},
child: const Text('Go to other page →'),
),
],
),
),
);
}
}
更多关于Flutter屏幕截图插件screenshooter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter屏幕截图插件screenshooter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用screenshooter
插件进行屏幕截图的示例代码。screenshooter
插件允许你轻松地在Flutter应用中捕获屏幕截图。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加screenshooter
插件的依赖:
dependencies:
flutter:
sdk: flutter
screenshooter: ^0.1.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置权限(Android)
对于Android设备,你需要在android/app/src/main/AndroidManifest.xml
文件中添加存储权限,以便保存截图:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 其他配置 -->
</manifest>
3. 使用插件
在你的Flutter代码中,你可以通过Screenshooter
类来捕获屏幕截图。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:screenshooter/screenshooter.dart';
import 'dart:io';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('ScreenShooter Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Capture Screenshot',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _captureScreenshot,
child: Text('Capture'),
),
],
),
),
),
);
}
Future<void> _captureScreenshot() async {
try {
File image = await Screenshooter.captureWithFileName('screenshot');
print('Screenshot saved to ${image.path}');
// 你可以在这里添加将截图显示到界面或者分享的逻辑
// 例如:_showSnackbar(image.path);
} catch (e) {
print('Error capturing screenshot: $e');
}
}
// 示例:使用Snackbar显示截图路径(可选)
void _showSnackbar(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
duration: Duration(seconds: 3),
),
);
}
}
4. 运行应用
现在,你可以运行你的Flutter应用,点击按钮时,它将会捕获当前屏幕截图并保存到设备存储中。
注意事项
- 截图文件名和路径可能会因设备和平台而异。
- 确保你已经处理了存储权限请求,特别是在Android 6.0(API级别23)及以上版本。
- 插件的API和用法可能会随着版本更新而变化,请参考插件的官方文档获取最新信息。
这个示例演示了如何在Flutter应用中使用screenshooter
插件进行屏幕截图。希望这对你有所帮助!