我试图做一个错误报告系统,当用户按下一个按钮时,它会拍摄屏幕的快照,然后允许他们发送它。我使用的是Screenshot包,并通过创建一个Scaffold Wrapper并用屏幕截图 Package 主Scaffold来设法让它工作。
我遇到的问题是,它的工作原理,但它提出了他的重复全局键的错误。解决这个问题是使屏幕截图控制器本地的Widget/页面,如在这里找到...
(Flutter error "Multiple widgets used the same GlobalKey" - using ScreenShot with SocialShare plugins)
但是,当处理多个页面时,我不想为每个页面创建一个控制器。
我已经尝试将控制器放置在一个提供程序中,该程序可以工作,但仍然存在一些重复全局密钥的问题。
我一直在寻找尝试的下一件事是使它的截图是本地的一个小部件,但提供商可以发送通知,该小部件,然后该小部件采取的图像,并将其发送回提供商.然而,经过多次尝试,我一直无法找到一种方法来做到这一点.我是相当新的Flutter约2-3个月,所以原谅我,如果我使用错误的术语.如果你需要更多的信息,请告诉我。
下面是代码示例
**这里是脚手架 Package **
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:screenshot/screenshot.dart';
import '../repository/constants.dart';
class ScaffoldWrapper extends StatefulWidget {
final Widget scaffold;
Function()? testFunction1;
ScaffoldWrapper({super.key, required this.scaffold, this.testFunction1});
static const redColor = Color.fromARGB(255, 213, 115, 57);
static const textColor = Color(0xff483538);
static const buttonColor = Color(0xff43060f);
static const bgColor = Color(0xff0A0B10);
static const bgGradientColor = Color.fromARGB(255, 213, 115, 57);
@override
State<ScaffoldWrapper> createState() => _ScaffoldWrapperState();
}
class _ScaffoldWrapperState extends State<ScaffoldWrapper> {
@override
@override
initState() {
super.initState();
}
bool devMode = true;
@override
Widget build(BuildContext context) {
return Screenshot(
controller: screenshotController,
child: Scaffold(
backgroundColor: ScaffoldWrapper.bgColor,
appBar: devMode
? AppBar(actions: [
ElevatedButton(
onPressed: () => widget.testFunction1!(),
child: const Text("Test Button 1")),
ElevatedButton(
onPressed: () {
Hive.box("USER_PREFERENCES").clear();
Hive.box("USER_DATA").clear();
},
child: const Text("Clear Data")),
ElevatedButton(
onPressed: () {Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ShowScreenshot()));},
child: const Text("Trigger Screenshot"))
])
: null,
extendBody: true,
body: Stack(
children: [
dradient(-1.0, -1.0),
dradient(1, 0),
Positioned(
child: widget.scaffold,
)
],
),
),
);
}
Container dradient(double x, double y) => Container(
decoration: BoxDecoration(
gradient: RadialGradient(
colors: [
ScaffoldWrapper.bgGradientColor.withOpacity(0.2),
ScaffoldWrapper.bgGradientColor.withOpacity(0)
],
radius: (0.8),
stops: const <double>[0, 1],
center: Alignment(x, y)),
),
);
}
常量文件包含控制器
ScreenshotController screenshotController = ScreenshotController();
使用Scaffold Wrapper的Widget示例
import 'package:flutter/material.dart';
import 'package:teacher_app_design/repository/constants.dart';
import 'package:teacher_app_design/widgets/custom_scaffold_wrapper.dart';
class ShowScreenshot extends StatefulWidget {
const ShowScreenshot({super.key});
@override
State<ShowScreenshot> createState() => _ShowScreenshotState();
}
class _ShowScreenshotState extends State<ShowScreenshot> {
@override
var screenshot;
@override
Widget build(BuildContext context) {
return ScaffoldWrapper(
scaffold: Scaffold(
body: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
const Center(
child: Text("Take Picture of this Page"),
),
ElevatedButton(
onPressed: () async {
await screenshotController.capture().then((value) {
screenshot = value;
});
showGeneralDialog(
context: context,
pageBuilder: (context, a1, a2) => Scaffold(
body: Center(
child: screenshot != null
? InteractiveViewer(
child: Image.memory(screenshot))
: Container()),
));
},
child: const Text('Take Screenshot'))
]),
),
);
}
}
对此问题的任何解决方案将不胜感激。
1条答案
按热度按时间wgmfuz8q1#
休息了一会儿之后,我设法找到了一个解决方案。
我只是在ScaffoldWrapper中使用provider方法和set来添加一个Listener。然后在Provider中创建一个bool变量并创建一个toggle函数。
当该值被切换时,它会通知侦听器,并且在ScaffoldWrapper中,侦听器被设置为使用本地screenShot Controller捕获并将值发送到Provider. screenshot。
然后我可以访问这个Provider.screenshot无论我需要它。
没有全局关键问题!
变化在----行之间。
和供应商。
我知道我不需要在提供程序中切换一个值,因为notifyListener会提醒ScaffoldWrapper中的侦听器,但它会帮助我了解它在做什么,当我将来回到它时。