flutter - 截屏隐藏 Flutter 中的一些小部件
问题描述
我想截取屏幕截图,但我想在生成的截图中隐藏/模糊/绘制一些小部件,而不是在应用程序中。像这样的东西:
第一张图片是我想在应用程序中看到的,没有变化。第二张图片是我想在屏幕截图中看到的,绘制了一个特定的小部件。
我的第一个想法是计算特定小部件的绝对坐标,但为了做到这一点,我应该为屏幕的每个小部件添加一个 GlobalKey,这对于我的情况是不可行的。
如何在不向屏幕的每个小部件添加 GlobalKey的情况下执行此操作?
我目前截取屏幕截图的方法是:
final pixelRatio = MediaQuery.of(context).devicePixelRatio;
final boundary = boundaryKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage(pixelRatio: pixelRatio);
这就是我用来获取具有 GlobalKey 的 Widget 坐标的方法:
extension GlobalKeyExtension on GlobalKey {
Rect? get globalPaintBounds {
final renderObject = currentContext?.findRenderObject();
var translation = renderObject?.getTransformTo(null).getTranslation();
if (translation != null) {
return renderObject!.paintBounds
.shift(Offset(translation.x, translation.y));
} else {
return null;
}
}
}
解决方案
屏幕截图小部件是您正在寻找的。
在您的 pubspec.yaml 文件中,在依赖项下添加以下行
dependencies:
screenshot: ^0.3.0
然后你可以像这样使用它。我只是添加了一些按钮和容器来展示它。您可以根据需要对其进行自定义。基本上这样做是当您将小部件作为具有控制器的屏幕截图小部件的子级时,您可以将其捕获为图像。
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:screenshot/screenshot.dart';
class ScreenCapture extends StatefulWidget {
ScreenCapture({Key key}) : super(key: key);
@override
_ScreenCaptureState createState() => _ScreenCaptureState();
}
class _ScreenCaptureState extends State<ScreenCapture> {
Uint8List _imageFile;
Color captureColor = Colors.red, inAppColor = Colors.green, inAppImageBG;
String capturingText = "Capturing State";
String inAppDisplayText = "In App Display";
String inAppText;
ScreenshotController screenshotController = new ScreenshotController();
@override
void initState() {
super.initState();
inAppImageBG = inAppColor;
inAppText = inAppDisplayText;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [capturedImageContainer(), inAppImage(), capture()],
),
);
}
Widget capturedImageContainer() {
return _imageFile != null
? Container(
color: Colors.black,
height: 100,
width: 300,
child: Image.memory(_imageFile),
)
: Container(color: Colors.black, height: 100, width: 300);
}
Widget inAppImage() {
return Screenshot(
controller: screenshotController,
child: Container(
color: inAppImageBG,
height: 100,
width: 300,
child: Text(inAppText),
alignment: Alignment.center,
),
);
}
Widget capture() {
return GestureDetector(
onTap: () {
doCapture();
},
child: Container(
height: 100,
width: 300,
color: Colors.amber,
child: Text("Capture"),
alignment: Alignment.center,
),
);
}
doCapture() async {
Future.delayed(const Duration(milliseconds: 500), () {
setState(() {
inAppImageBG = captureColor;
inAppText = capturingText + Random().nextInt(10).toString();
Future.delayed(const Duration(milliseconds: 10), () {
screenshotController
.capture(delay: Duration(milliseconds: 1))
.then((Uint8List image) async {
setState(() {
_imageFile = image;
Future.delayed(const Duration(milliseconds: 1500), () {
setState(() {
inAppImageBG = inAppColor;
inAppText = inAppDisplayText;
});
});
});
}).catchError((onError) {
print(onError);
});
});
});
});
}
}
推荐阅读
- javascript - 如何使用 JavaScript 打开 Google Assistant App?
- java - LinearLayoutManager 不能在 Fragment 中使用
- asp.net - NLog获取当前用户会导致出现错误
- latex - 使用 RMarkdown 编织“大于或等于”符号时 PDF 输出失败
- flash - 闪存实现中的循环缓冲区
- java - 无法在 JSP 页面中显示图像
- javascript - 使用回调函数查询
- c++ - 为什么在 c++20 中不推荐使用 std::filesystem::u8path?
- android - 如何将数据从 Activity 传递到 CustomView?
- javascript - 如何通过 sequelize.js 使用云端数据库?