再次修改版
This commit is contained in:
parent
b6a1e84658
commit
120cccf235
|
|
@ -0,0 +1,147 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
enum TransitionType {
|
||||
///左侧弹出
|
||||
inFromLeft,
|
||||
///右侧弹出
|
||||
inFromRight,
|
||||
///顶部弹出
|
||||
inFromTop,
|
||||
///底部弹出
|
||||
inFromBottom,
|
||||
///缩放
|
||||
scale,
|
||||
///渐变
|
||||
fade,
|
||||
///旋转缩放
|
||||
rotation,
|
||||
///放大
|
||||
size,
|
||||
}
|
||||
|
||||
|
||||
//弹出动画
|
||||
// barrierDismissible:点击背景是否消失
|
||||
// child,builder:子 widget
|
||||
// useRootNavigator: 是否推入传入 context的 导航器
|
||||
// routeSettings: 弹窗路由设置
|
||||
Future<T?> showAnimationDialog<T>({
|
||||
required BuildContext context,
|
||||
bool barrierDismissible = true,
|
||||
Widget? child,
|
||||
WidgetBuilder? builder,
|
||||
bool useRootNavigator = true,
|
||||
RouteSettings? routeSettings,
|
||||
TransitionType? transitionType,
|
||||
}) {
|
||||
assert(child == null || builder == null);
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
final ThemeData theme = Theme.of(context);
|
||||
return showGeneralDialog(
|
||||
context: context,
|
||||
pageBuilder: (BuildContext buildContext, Animation<double> animation, Animation<double> secondaryAnimation) {
|
||||
final Widget pageChild = child ?? Builder(builder: builder!);
|
||||
return SafeArea(
|
||||
child: Builder(builder: (BuildContext context) {
|
||||
return Theme(data: theme, child: pageChild);
|
||||
}),
|
||||
);
|
||||
},
|
||||
barrierDismissible: barrierDismissible, ///点击背景是否消失
|
||||
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||
barrierColor: Colors.black38, ///背景色
|
||||
transitionDuration: const Duration(milliseconds: 200),///动画时间
|
||||
transitionBuilder: (context, animation1, animation2, child) { ///动画效果
|
||||
return _buildDialogTransitions(context, animation1, animation2, child, transitionType?? TransitionType.inFromBottom);
|
||||
},
|
||||
useRootNavigator: useRootNavigator,
|
||||
routeSettings: routeSettings,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
///返回动画效果
|
||||
Widget _buildDialogTransitions(
|
||||
BuildContext context, Animation<double> animaton1, Animation<double> secondaryAnimation, Widget child, TransitionType type) {
|
||||
|
||||
/// 渐变效果
|
||||
if (type == TransitionType.fade) {
|
||||
return FadeTransition(
|
||||
// 从0开始到1
|
||||
opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
|
||||
// 传入设置的动画
|
||||
parent: animaton1,
|
||||
// 设置效果,快进漫出 这里有很多内置的效果
|
||||
curve: Curves.fastOutSlowIn,
|
||||
)),
|
||||
child: child,
|
||||
);
|
||||
|
||||
///缩放
|
||||
} else if (type == TransitionType.scale) {
|
||||
return ScaleTransition(
|
||||
scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.easeOutBack)),//Curves.easeOutBack
|
||||
child: child,
|
||||
);
|
||||
|
||||
/// 旋转加缩放动画效果
|
||||
} else if (type == TransitionType.rotation) {
|
||||
|
||||
return RotationTransition(
|
||||
turns: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
|
||||
parent: animaton1,
|
||||
curve: Curves.fastOutSlowIn,
|
||||
)),
|
||||
child: ScaleTransition(
|
||||
scale: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
|
||||
/// 左滑出动画效果
|
||||
} else if (type == TransitionType.inFromLeft) {
|
||||
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset(0.0, 0.0))
|
||||
.animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
child: child,
|
||||
);
|
||||
|
||||
/// 右滑出动画效果
|
||||
} else if (type == TransitionType.inFromRight) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0))
|
||||
.animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
child: child,
|
||||
);
|
||||
|
||||
/// 顶部滑出动画效果
|
||||
} else if (type == TransitionType.inFromTop) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(begin: Offset(0.0, -1.0), end: Offset(0.0, 0.0))
|
||||
.animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
child: child,
|
||||
);
|
||||
|
||||
/// 底部滑出动画效果
|
||||
} else if (type == TransitionType.inFromBottom) {
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(begin: Offset(0.0, 1.0), end: Offset(0.0, 0.0))
|
||||
.animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
child: child,
|
||||
);
|
||||
|
||||
/// 放大出显动画效果
|
||||
} else if (type == TransitionType.size) {
|
||||
return ScaleTransition(
|
||||
child: child,
|
||||
scale: Tween<double>(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animaton1, curve: Curves.fastOutSlowIn)),
|
||||
);
|
||||
} else {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -6,10 +6,51 @@ import 'package:webview_windows/webview_windows.dart';
|
|||
|
||||
class SynchronizationWebTool{
|
||||
|
||||
// 私有构造函数
|
||||
SynchronizationWebTool._();
|
||||
// 私有静态变量,保存类的唯一实例
|
||||
static SynchronizationWebTool? _instance;
|
||||
|
||||
// 公开的静态方法,返回类的唯一实例
|
||||
static SynchronizationWebTool getInstance() {
|
||||
_instance ??= SynchronizationWebTool._();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
bool webSync = false;
|
||||
|
||||
/// 主控
|
||||
late WebviewController mainController;
|
||||
/// 受控
|
||||
List<WebviewController> childController = [];
|
||||
List<WebviewController> _childControllers = [];
|
||||
|
||||
setChildController(List<WebviewController> childControllers){
|
||||
|
||||
for (var controller in childControllers) {
|
||||
controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
||||
controller.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadZoom(90));
|
||||
}
|
||||
|
||||
mainController = childControllers.first;
|
||||
_childControllers = childControllers.sublist(1,10);
|
||||
|
||||
mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
||||
mainController.webMessage.listen((event) {
|
||||
print('mainController listen -- $event');
|
||||
if (event['click'] != null && webSync) {
|
||||
Map click = event['click'];
|
||||
double x = (click['x'] as int).toDouble();
|
||||
double y = (click['y'] as int).toDouble();
|
||||
|
||||
clickSynchronization(x, y);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
List<WebviewController> get childController{
|
||||
return _childControllers;
|
||||
}
|
||||
|
||||
/// 点击同步
|
||||
clickSynchronization(double x,double y){
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:web_synchronization_tool/windows/show_animation_utils.dart';
|
||||
import 'package:web_synchronization_tool/windows/synchronization_web_tool.dart';
|
||||
import 'package:web_synchronization_tool/windows/windowsJs.dart';
|
||||
import 'package:webview_windows/webview_windows.dart';
|
||||
|
||||
class WebGridController {
|
||||
|
||||
Function(WebviewController controller)? addWebControllerBlack;
|
||||
|
||||
addWebController(WebviewController controller) {
|
||||
if (addWebControllerBlack != null) {
|
||||
addWebControllerBlack!(controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WebGridWidget extends StatefulWidget {
|
||||
const WebGridWidget({super.key, required this.controller});
|
||||
|
||||
final WebGridController controller;
|
||||
|
||||
@override
|
||||
State<WebGridWidget> createState() => _WebGridWidgetState();
|
||||
}
|
||||
|
||||
class _WebGridWidgetState extends State<WebGridWidget> {
|
||||
|
||||
List<WebviewController> controllers = [];
|
||||
|
||||
bool initDone = false;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
controllerInit();
|
||||
}
|
||||
|
||||
Future controllerInit() async {
|
||||
|
||||
for (var i = 0; i< 10 ; i++) {
|
||||
var controller = WebviewController();
|
||||
await controller.initialize();
|
||||
controller.loadUrl('http://www.df6831.com/');
|
||||
|
||||
// controller.executeScript(WindowsJs.zoom(35));
|
||||
// controller.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadZoom(35));
|
||||
|
||||
controllers.add(controller);
|
||||
}
|
||||
|
||||
SynchronizationWebTool.getInstance().setChildController(controllers);
|
||||
|
||||
setState(() {
|
||||
initDone = true;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 5, // 两列
|
||||
crossAxisSpacing: 8.0, // 水平间距
|
||||
mainAxisSpacing: 8.0, // 垂直间距
|
||||
childAspectRatio: 0.9),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Stack(
|
||||
children: [
|
||||
Webview(controllers[index]),
|
||||
TextButton(
|
||||
style: ButtonStyle(
|
||||
overlayColor: MaterialStateProperty.resolveWith(
|
||||
(states) => Colors.transparent)),
|
||||
onPressed: () {
|
||||
|
||||
var controller = controllers[index];
|
||||
// controller.executeScript(WindowsJs.zoom(100));
|
||||
|
||||
showAnimationDialog(
|
||||
context: context,
|
||||
// barrierDismissible: false,
|
||||
child: ShowWebWidget(controller: controller,));
|
||||
},
|
||||
child: Container(),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
itemCount: controllers.length, // 生成20个瀑布流瓦片
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ShowWebWidget extends StatelessWidget {
|
||||
const ShowWebWidget({super.key, required this.controller});
|
||||
|
||||
final WebviewController controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 1400,
|
||||
height: 900,
|
||||
child: Webview(controller),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -5,31 +5,37 @@ document.addEventListener("click", function (event) {
|
|||
var x = event.clientX;
|
||||
var y = event.clientY;
|
||||
|
||||
var click = { 'x': x, 'y': y };
|
||||
// var value = { click: click };
|
||||
var click = { "x": x, "y": y };
|
||||
var value = { click: click };
|
||||
|
||||
// 发送消息
|
||||
window.chrome.webview.postMessage(click);
|
||||
window.chrome.webview.postMessage(value);
|
||||
|
||||
window.chrome.webview.postMessage({"text":event.target.textContent,"end":event.target.textContent === "进入游戏"});
|
||||
|
||||
// 检查点击的元素是否有类名为 'btn'
|
||||
if (event.target.classList.contains("btn")) {
|
||||
if (event.target.textContent === "进入游戏") {
|
||||
// 获取按钮上显示的文本内容
|
||||
var buttonText = event.target.innerText;
|
||||
|
||||
if (buttonText == "进入游戏") {
|
||||
var btn = { x: "成功获取到btn", y: buttonText };
|
||||
window.chrome.webview.postMessage(btn);
|
||||
window.chrome.webview.postMessage({ "成功获取到btn": 1 });
|
||||
// window.chrome.webview.postMessage({ "btn": event.target.textContent });
|
||||
|
||||
// 阻止默认的链接跳转行为
|
||||
event.preventDefault();
|
||||
|
||||
var newUrl = this.href; // 获取点击链接的跳转地址
|
||||
var oldUrl = window.location.href;
|
||||
var classUrl = event.target.href;
|
||||
|
||||
var str = oldUrl;
|
||||
var startIndex = str.indexOf('www.');
|
||||
var endIndex = str.indexOf('/', startIndex);
|
||||
var url = str.substring(startIndex, endIndex);
|
||||
var newUrl = "https://" + url + "/game/";
|
||||
|
||||
window.chrome.webview.postMessage({"元素地址": classUrl ,"旧地址":window.location.href ,"截取":url,"新地址": newUrl});
|
||||
// 在当前窗口打开目标地址
|
||||
// window.location.href = "http://www.df6831.com/game/";
|
||||
window.location.href = newUrl;
|
||||
window.chrome.webview.postMessage({url:newUrl}});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
''';
|
||||
|
|
@ -54,28 +60,27 @@ document.addEventListener("click", function (event) {
|
|||
|
||||
|
||||
/// 监听加载,在加载完成后缩放
|
||||
static String onloadScale(int scale){
|
||||
assert(scale >= 1 && scale <= 100, 'zoom 1 到 100');
|
||||
static String onloadZoom(int zoom){
|
||||
assert(zoom >= 1 && zoom <= 100, 'zoom 1 到 100');
|
||||
return '''
|
||||
window.onload = function () {
|
||||
// 修改页面缩放比例为0.5(50%)
|
||||
document.body.style.transformOrigin = 'top left';
|
||||
document.body.style.transform = 'scale(${scale / 100})';
|
||||
var currentUrl = window.location.href;
|
||||
if (currentUrl.endsWith('game/')) {
|
||||
${WindowsJs.zoom(zoom)}
|
||||
}
|
||||
};
|
||||
''';
|
||||
}
|
||||
|
||||
|
||||
/// 修改缩放
|
||||
static String scale(int scale){
|
||||
assert(scale >= 1 && scale <= 100, 'zoom 1 到 100');
|
||||
static String zoom(int zoom){
|
||||
assert(zoom >= 1 && zoom <= 100, 'zoom 1 到 100');
|
||||
return '''
|
||||
// document.body.style.zoom = "$scale%";
|
||||
document.body.style.transformOrigin = 'top left';
|
||||
document.body.style.transform = 'scale(${scale / 100})';
|
||||
document.body.style.zoom = "$zoom%";
|
||||
''';
|
||||
}
|
||||
|
||||
static String message = 'window.chrome.webview.postMessage({x:3333}});';
|
||||
static String message = 'window.chrome.webview.postMessage({x:3333});';
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:web_synchronization_tool/windows/synchronization_web_tool.dart';
|
||||
import 'package:web_synchronization_tool/windows/web_grid_view.dart';
|
||||
import 'package:web_synchronization_tool/windows/windowsJs.dart';
|
||||
import 'windows_web_page.dart';
|
||||
import 'package:webview_windows/webview_windows.dart';
|
||||
|
|
@ -11,11 +13,15 @@ class WindowsPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _WindowsPageState extends State<WindowsPage> {
|
||||
final mainController = WebviewController();
|
||||
final controller = WebviewController();
|
||||
Widget? windowsWebWidget;
|
||||
WebviewController mainController = WebviewController();
|
||||
final gridController = WebGridController();
|
||||
|
||||
bool initDone = false;
|
||||
|
||||
String clickId = '';
|
||||
String zoomId = '';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -24,42 +30,31 @@ class _WindowsPageState extends State<WindowsPage> {
|
|||
}
|
||||
|
||||
Future controllerInit() async {
|
||||
|
||||
await mainController.initialize();
|
||||
await controller.initialize();
|
||||
|
||||
|
||||
mainController.loadUrl('http://www.df6831.com/');
|
||||
controller.loadUrl('http://www.df6831.com/');
|
||||
|
||||
addClickEventJS();
|
||||
gridController.addWebController(mainController);
|
||||
|
||||
setState(() {
|
||||
initDone = true;
|
||||
});
|
||||
|
||||
// controller.setUserAgent('Mobile');
|
||||
|
||||
/// 通道消息
|
||||
mainController.webMessage.listen((event) {
|
||||
print('mainController listen -- $event');
|
||||
// controller.executeScript(WindowsJs.clickJs(event['x'], event['y']));
|
||||
});
|
||||
|
||||
/// 通道消息
|
||||
controller.webMessage.listen((event) {
|
||||
// print('controller listen -- $event');
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 注入点击监听
|
||||
addClickEventJS() async {
|
||||
ScriptID? scriptId = await mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
||||
// mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadScale(70));
|
||||
// mainController.removeScriptToExecuteOnDocumentCreated(scriptId?? '');
|
||||
controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
||||
/// 开启通道消息
|
||||
eventMessage() {
|
||||
// 通道消息
|
||||
// mainController.webMessage.listen((event) {
|
||||
// print('mainController listen -- $event');
|
||||
// if (event['click'] != null && webSync) {
|
||||
// Map click = event['click'];
|
||||
// double x = (click['x'] as int).toDouble();
|
||||
// double y = (click['y'] as int).toDouble();
|
||||
// x = x * (0.4 / 0.7);
|
||||
// y = y * (0.4 / 0.7);
|
||||
// // controller.executeScript(WindowsJs.clickJs(x, y));
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -75,45 +70,61 @@ class _WindowsPageState extends State<WindowsPage> {
|
|||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
child: Row(
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.executeScript(WindowsJs.clickJs(200, 900));
|
||||
// controller.executeScript(WindowsJs.clickJs(600, 100));
|
||||
},
|
||||
child: const Text('模拟点击测试')),
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// mainController.executeScript(WindowsJs.clickJs(200, 900));
|
||||
// },
|
||||
// child: const Text('模拟点击测试')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.executeScript(WindowsJs.inputJs(45));
|
||||
controller.executeScript(WindowsJs.inputJs(45));
|
||||
// controller.executeScript(WindowsJs.inputJs(45));
|
||||
},
|
||||
child: const Text('模拟输入测试')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.loadUrl('http://www.df6831.com/');
|
||||
mainController.loadUrl('https://www.baidu.com/');
|
||||
},
|
||||
child: const Text('跳转首页')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.executeScript(WindowsJs.scale(70));
|
||||
controller.executeScript(WindowsJs.scale(40));
|
||||
SynchronizationWebTool.getInstance().childController.forEach((controller) {
|
||||
controller.executeScript(WindowsJs.zoom(35));
|
||||
});
|
||||
// 468, 72
|
||||
// controller.executeScript(WindowsJs.zoom(40));// 239,39
|
||||
},
|
||||
child: const Text('缩放')),
|
||||
//
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.openDevTools();
|
||||
mainController
|
||||
.executeScript('window.resizeBy(-100, -100);');
|
||||
},
|
||||
child: const Text('开发者')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.clearCookies();
|
||||
mainController.clearCache();
|
||||
},
|
||||
child: const Text('清除缓存')),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
mainController.executeScript(WindowsJs.message);
|
||||
},
|
||||
child: const Text('发送消息')),
|
||||
child: const Text('减少尺寸')),
|
||||
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// mainController.openDevTools();
|
||||
// },
|
||||
// child: const Text('开发者')),
|
||||
// TextButton(
|
||||
// onPressed: () {
|
||||
// mainController.executeScript(WindowsJs.message);
|
||||
// },
|
||||
// child: const Text('发送消息')),
|
||||
Row(
|
||||
children: [
|
||||
const Text('同步'),
|
||||
Switch(
|
||||
value: SynchronizationWebTool.getInstance().webSync,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
SynchronizationWebTool.getInstance().webSync = value;
|
||||
});
|
||||
})
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -127,42 +138,20 @@ class _WindowsPageState extends State<WindowsPage> {
|
|||
Widget pageViewWidget() {
|
||||
return Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 1350,
|
||||
height: 1000,
|
||||
child: WindowsWebWidget(
|
||||
controller: mainController,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 550,
|
||||
height:400,
|
||||
child: WindowsWebWidget(
|
||||
controller: controller,
|
||||
),
|
||||
)
|
||||
// SizedBox(
|
||||
// width: 1000,
|
||||
// height: 1000,
|
||||
// child: inWindowsWebView(),
|
||||
// ),
|
||||
Expanded(
|
||||
child: WebGridWidget(
|
||||
controller: gridController,
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class KeepAlivePage extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
||||
KeepAlivePage({super.key, required this.child});
|
||||
|
||||
@override
|
||||
_KeepAlivePageState createState() => _KeepAlivePageState();
|
||||
}
|
||||
|
||||
class _KeepAlivePageState extends State<KeepAlivePage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return widget.child;
|
||||
Widget inWindowsWebView() {
|
||||
return Webview(mainController);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ class WindowsWebWidget extends StatefulWidget {
|
|||
|
||||
class _WindowsWebWidgetState extends State<WindowsWebWidget> {
|
||||
|
||||
Webview? webview;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -21,7 +23,8 @@ class _WindowsWebWidgetState extends State<WindowsWebWidget> {
|
|||
}
|
||||
|
||||
Widget inWindowsWebView(){
|
||||
return Webview(widget.controller);
|
||||
webview ??= Webview(widget.controller);
|
||||
return webview!;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue