Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
f63ad460d5 | |
|
|
525e10badc | |
|
|
b6b6e41e8b | |
|
|
ff882a5e06 | |
|
|
30af057969 | |
|
|
e91a3a40af |
|
|
@ -30,12 +30,13 @@ class SyncSocket {
|
||||||
RawDatagramSocket? socket;
|
RawDatagramSocket? socket;
|
||||||
|
|
||||||
// IC 0主机 1 从机
|
// IC 0主机 1 从机
|
||||||
int ic = 1;
|
int ic = 0;
|
||||||
|
|
||||||
/// 从机ip
|
/// 从机ip
|
||||||
List<String> childrenIp = [];
|
List<String> childrenIp = [];
|
||||||
|
|
||||||
connect() async {
|
connect() async {
|
||||||
|
socket?.close();
|
||||||
socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
|
socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, 0);
|
||||||
|
|
||||||
// 发送身份包
|
// 发送身份包
|
||||||
|
|
@ -78,11 +79,48 @@ class SyncSocket {
|
||||||
if (data['op'] == 11){
|
if (data['op'] == 11){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// 服务器 已连接的ip
|
||||||
|
if (data['Arr'] != null){
|
||||||
|
List arr = data['Arr'];
|
||||||
|
List<String> ips = [];
|
||||||
|
arr.forEach((clientMap) {
|
||||||
|
String ip = clientMap['Client'];
|
||||||
|
ips.add(ip);
|
||||||
|
});
|
||||||
|
childrenIp = ips;
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 发送消息
|
||||||
|
sendClickMessage(Map data){
|
||||||
|
Map messageMap = {
|
||||||
|
"op": 2,
|
||||||
|
"click": data
|
||||||
|
};
|
||||||
|
socket?.send(dataMake(messageMap), InternetAddress(url), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 发送获取从机 消息
|
||||||
|
sendGetChilds(){
|
||||||
|
Map messageMap = {
|
||||||
|
"op": 3,
|
||||||
|
};
|
||||||
|
socket?.send(dataMake(messageMap), InternetAddress(url), port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// 发送输入喜消息
|
||||||
|
sendInpuMessage(int num){
|
||||||
|
Map messageMap = {
|
||||||
|
"op": 2,
|
||||||
|
"input": num
|
||||||
|
};
|
||||||
|
socket?.send(dataMake(messageMap), InternetAddress(url), port);
|
||||||
|
}
|
||||||
|
|
||||||
/// 心跳
|
/// 心跳
|
||||||
heartbeat(){
|
heartbeat(){
|
||||||
Timer timer = Timer(const Duration(seconds: 10), () async {
|
Timer timer = Timer(const Duration(seconds: 10), () async {
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,53 @@ class SynchronizationWebTool{
|
||||||
return _instance!;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool webSync = false;
|
||||||
|
|
||||||
|
/// 主控
|
||||||
|
late WebviewController mainController;
|
||||||
/// 受控
|
/// 受控
|
||||||
List<WebviewController> _childControllers = [];
|
List<WebviewController> _childControllers = [];
|
||||||
|
|
||||||
/// 设置控制器时 注入js
|
/// 设置控制器时 注入js
|
||||||
setChildController(List<WebviewController> childControllers){
|
setChildController(List<WebviewController> childControllers){
|
||||||
|
|
||||||
// for (var controller in childControllers) {
|
for (var controller in childControllers) {
|
||||||
// controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
controller.addScriptToExecuteOnDocumentCreated(WindowsJs.clickEventJs);
|
||||||
// // controller.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadZoom(90));
|
// controller.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadZoom(90));
|
||||||
// }
|
}
|
||||||
|
|
||||||
_childControllers = childControllers;
|
mainController = childControllers.first;
|
||||||
|
_childControllers = childControllers.sublist(1,10);
|
||||||
|
|
||||||
// 滚动监听
|
// 滚动监听
|
||||||
// mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.scrollEventJs);
|
// mainController.addScriptToExecuteOnDocumentCreated(WindowsJs.scrollEventJs);
|
||||||
|
|
||||||
|
mainController.webMessage.listen((event) {
|
||||||
|
print('mainController listen --');
|
||||||
|
|
||||||
|
if (event['scroll'] != null ) {
|
||||||
|
print(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!webSync) return;
|
||||||
|
|
||||||
|
if (event['click'] != null) {
|
||||||
|
Map click = event['click'];
|
||||||
|
int x = click['x'] as int;
|
||||||
|
int y = click['y'] as int;
|
||||||
|
|
||||||
|
clickSynchronization(x, y);
|
||||||
|
SocketUtils.getInstance().sendClickMessage(click);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event['scroll'] != null ) {
|
||||||
|
print(event);
|
||||||
|
int y = event['y'] as int;
|
||||||
|
scrollSynchronization(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WebviewController> get childController{
|
List<WebviewController> get childController{
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,20 @@
|
||||||
|
import 'package:common/utils/toast_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:web_synchronization_tool/windows/number_tool.dart';
|
||||||
import 'package:web_synchronization_tool/windows/socket_tool.dart';
|
import 'package:web_synchronization_tool/windows/socket_tool.dart';
|
||||||
import 'package:web_synchronization_tool/windows/synchronization_web_tool.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';
|
import 'package:webview_windows/webview_windows.dart';
|
||||||
|
|
||||||
class WebGridController {
|
class WebGridController {
|
||||||
Function(WebviewController controller)? addWebControllerBlack;
|
|
||||||
Function? addWebBlack;
|
|
||||||
Function? addAllWebBlack;
|
|
||||||
|
|
||||||
addMainController(WebviewController controller) {
|
Function(WebviewController controller)? addWebControllerBlack;
|
||||||
|
|
||||||
|
addWebController(WebviewController controller) {
|
||||||
if (addWebControllerBlack != null) {
|
if (addWebControllerBlack != null) {
|
||||||
addWebControllerBlack!(controller);
|
addWebControllerBlack!(controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addWeb() {
|
|
||||||
if (addWebBlack != null) {
|
|
||||||
addWebBlack!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addAllWeb() {
|
|
||||||
if (addAllWebBlack != null) {
|
|
||||||
addAllWebBlack!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WebGridWidget extends StatefulWidget {
|
class WebGridWidget extends StatefulWidget {
|
||||||
|
|
@ -37,135 +27,88 @@ class WebGridWidget extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WebGridWidgetState extends State<WebGridWidget> {
|
class _WebGridWidgetState extends State<WebGridWidget> {
|
||||||
|
|
||||||
List<WebviewController> controllers = [];
|
List<WebviewController> controllers = [];
|
||||||
|
|
||||||
bool initDone = false;
|
bool initDone = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
widget.controller.addWebBlack = () {
|
controllerInit();
|
||||||
addController();
|
|
||||||
};
|
|
||||||
|
|
||||||
widget.controller.addAllWebBlack = () {
|
|
||||||
addAllController();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提娜佳一个网页
|
/// 控制器初始化
|
||||||
addController() async {
|
Future controllerInit() async {
|
||||||
if (controllers.length >= 10) return;
|
|
||||||
|
|
||||||
var controller = WebviewController();
|
for (var i = 0; i< 10 ; i++) {
|
||||||
await controller.initialize();
|
|
||||||
controller.loadUrl('https://www.df6831.com/');
|
|
||||||
|
|
||||||
controllers.add(controller);
|
|
||||||
SynchronizationWebTool.getInstance().setChildController(controllers);
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将网页加满到10个
|
|
||||||
addAllController() async {
|
|
||||||
final num = 10 - controllers.length;
|
|
||||||
if (num < 1) return;
|
|
||||||
|
|
||||||
for (int i = 0; i < num; i++) {
|
|
||||||
var controller = WebviewController();
|
var controller = WebviewController();
|
||||||
await controller.initialize();
|
await controller.initialize();
|
||||||
controller.loadUrl('https://www.df6831.com/');
|
controller.loadUrl('https://www.df6831.com/');
|
||||||
|
|
||||||
|
// controller.executeScript(WindowsJs.zoom(35));
|
||||||
|
// controller.addScriptToExecuteOnDocumentCreated(WindowsJs.onloadZoom(35));
|
||||||
|
|
||||||
controllers.add(controller);
|
controllers.add(controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronizationWebTool.getInstance().setChildController(controllers);
|
SynchronizationWebTool.getInstance().setChildController(controllers);
|
||||||
setState(() {});
|
|
||||||
|
setState(() {
|
||||||
|
initDone = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Stack(
|
return GridView.builder(
|
||||||
children: [
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
GridView.builder(
|
crossAxisCount: 5, // 两列
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
crossAxisSpacing: 8.0, // 水平间距
|
||||||
crossAxisCount: 5, // 两列
|
mainAxisSpacing: 8.0, // 垂直间距
|
||||||
crossAxisSpacing: 8.0, // 水平间距
|
childAspectRatio: 0.9),
|
||||||
mainAxisSpacing: 8.0, // 垂直间距
|
itemBuilder: (BuildContext context, int index) {
|
||||||
childAspectRatio: 0.9),
|
return Stack(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
children: [
|
||||||
return Stack(
|
Webview(controllers[index]),
|
||||||
children: [
|
TextButton(
|
||||||
Webview(controllers[index]),
|
style: ButtonStyle(
|
||||||
TextButton(
|
overlayColor: MaterialStateProperty.resolveWith(
|
||||||
style: ButtonStyle(
|
(states) => Colors.transparent)),
|
||||||
overlayColor: MaterialStateProperty.resolveWith(
|
onPressed: () {
|
||||||
(states) => Colors.transparent)),
|
|
||||||
onPressed: () {
|
|
||||||
var controller = controllers[index];
|
|
||||||
// controller.executeScript(WindowsJs.zoom(100));
|
|
||||||
|
|
||||||
// showAnimationDialog(
|
var controller = controllers[index];
|
||||||
// context: context,
|
// controller.executeScript(WindowsJs.zoom(100));
|
||||||
// // barrierDismissible: false,
|
|
||||||
// child: ShowWebWidget(controller: controller,));
|
|
||||||
|
|
||||||
// Navigator.push(context, MaterialPageRoute(builder: (context)=> ShowWebWidget(controller: controller,) ));
|
// showAnimationDialog(
|
||||||
|
// context: context,
|
||||||
|
// // barrierDismissible: false,
|
||||||
|
// child: ShowWebWidget(controller: controller,));
|
||||||
|
|
||||||
Navigator.of(context).push(PageRouteBuilder(
|
// Navigator.push(context, MaterialPageRoute(builder: (context)=> ShowWebWidget(controller: controller,) ));
|
||||||
opaque: false, // 设置路由本身透明
|
|
||||||
pageBuilder: (BuildContext context, _, __) =>
|
Navigator.of(context).push(PageRouteBuilder(
|
||||||
ShowWebWidget(
|
opaque: false, // 设置路由本身透明
|
||||||
controller: controller,
|
pageBuilder: (BuildContext context, _, __) => ShowWebWidget(controller: controller,main: index == 0,),
|
||||||
main: index == 0,
|
));
|
||||||
allLoadUrl: (String url) {
|
|
||||||
controllers.forEach((controller) {
|
},
|
||||||
controller.loadUrl(url);
|
child: Container(),
|
||||||
});
|
)
|
||||||
},
|
],
|
||||||
),
|
);
|
||||||
));
|
},
|
||||||
},
|
itemCount: controllers.length, // 生成20个瀑布流瓦片
|
||||||
child: Container(),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.topRight,
|
|
||||||
child: TextButton(
|
|
||||||
style: TextButton.styleFrom(padding: const EdgeInsets.all(0)),
|
|
||||||
onPressed: () {
|
|
||||||
controllers.removeAt(index);
|
|
||||||
SynchronizationWebTool.getInstance()
|
|
||||||
.setChildController(controllers);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.blue[100],
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: const Icon(Icons.clear)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
itemCount: controllers.length, // 生成20个瀑布流瓦片
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ShowWebWidget extends StatefulWidget {
|
class ShowWebWidget extends StatefulWidget {
|
||||||
const ShowWebWidget(
|
const ShowWebWidget({super.key, required this.controller, this.main = false});
|
||||||
{super.key,
|
|
||||||
required this.controller,
|
|
||||||
this.main = false,
|
|
||||||
required this.allLoadUrl});
|
|
||||||
|
|
||||||
final WebviewController controller;
|
final WebviewController controller;
|
||||||
|
|
||||||
final Function(String url) allLoadUrl;
|
|
||||||
|
|
||||||
final bool main;
|
final bool main;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -173,11 +116,13 @@ class ShowWebWidget extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ShowWebWidgetState extends State<ShowWebWidget> {
|
class _ShowWebWidgetState extends State<ShowWebWidget> {
|
||||||
/// 网址
|
|
||||||
TextEditingController urlController = TextEditingController();
|
|
||||||
|
|
||||||
/// 服务器ip
|
/// 网址
|
||||||
TextEditingController ipController = TextEditingController();
|
TextEditingController urlController = TextEditingController();
|
||||||
|
/// 总金额
|
||||||
|
TextEditingController numController = TextEditingController();
|
||||||
|
/// 服务器ip
|
||||||
|
TextEditingController ipController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
|
@ -204,15 +149,26 @@ class _ShowWebWidgetState extends State<ShowWebWidget> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getTitleWidget() {
|
Widget getTitleWidget(){
|
||||||
if (widget.main == false) return input();
|
if (widget.main == false) return input();
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
// TextButton(
|
inputNumber(),
|
||||||
// onPressed: () {
|
Row(
|
||||||
// widget.controller.openDevTools();
|
children: [
|
||||||
// },
|
const Text('同步'),
|
||||||
// child: const Text('开发者')),
|
Switch(
|
||||||
|
value: SynchronizationWebTool.getInstance().webSync,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
SynchronizationWebTool.getInstance().webSync = value;
|
||||||
|
if (value){ // 打开同步获取 从机
|
||||||
|
SocketUtils.getInstance().sendGetChilds();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
input(),
|
input(),
|
||||||
ipSet()
|
ipSet()
|
||||||
],
|
],
|
||||||
|
|
@ -220,61 +176,69 @@ class _ShowWebWidgetState extends State<ShowWebWidget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 跳转网址
|
/// 跳转网址
|
||||||
input() {
|
input(){
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(width: 400, child: TextField(style: const TextStyle(fontSize: 14),controller: urlController,)),
|
||||||
width: 400,
|
TextButton(onPressed: (){
|
||||||
child: TextField(
|
String url = urlController.text;
|
||||||
style: const TextStyle(fontSize: 14),
|
// if (!url.startsWith("https://") ) {
|
||||||
controller: urlController,
|
// url = "https://$url";
|
||||||
)),
|
// }
|
||||||
TextButton(
|
widget.controller.loadUrl(url);
|
||||||
onPressed: () {
|
}, child: const Text('跳转',style: TextStyle(fontSize: 14),))
|
||||||
String url = urlController.text;
|
|
||||||
// if (!url.startsWith("https://") ) {
|
|
||||||
// url = "https://$url";
|
|
||||||
// }
|
|
||||||
widget.controller.loadUrl(url);
|
|
||||||
},
|
|
||||||
child: const Text(
|
|
||||||
'跳转',
|
|
||||||
style: TextStyle(fontSize: 14),
|
|
||||||
)),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
String url = urlController.text;
|
|
||||||
|
|
||||||
widget.allLoadUrl(url);
|
|
||||||
},
|
|
||||||
child: const Text(
|
|
||||||
'全部跳转',
|
|
||||||
style: TextStyle(fontSize: 14),
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipSet() {
|
ipSet(){
|
||||||
ipController.text = SocketUtils.getInstance().url;
|
ipController.text = SocketUtils.getInstance().url;
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(width: 100, child: TextField(style: const TextStyle(fontSize: 14),controller: ipController,)),
|
||||||
width: 100,
|
TextButton(onPressed: (){
|
||||||
child: TextField(
|
SocketUtils.getInstance().url = ipController.text;
|
||||||
style: const TextStyle(fontSize: 14),
|
SocketUtils.getInstance().connect();
|
||||||
controller: ipController,
|
}, child: const Text('保存服务器ip',style: TextStyle(fontSize: 14),))
|
||||||
)),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
SocketUtils.getInstance().url = ipController.text;
|
|
||||||
SocketUtils.getInstance().connect();
|
|
||||||
},
|
|
||||||
child: const Text(
|
|
||||||
'保存服务器ip',
|
|
||||||
style: TextStyle(fontSize: 14),
|
|
||||||
))
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 输入总金额
|
||||||
|
inputNumber(){
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(width: 100, child: TextField(style: const TextStyle(fontSize: 14),controller: numController,)),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
try{
|
||||||
|
int num = int.parse(numController.text);
|
||||||
|
|
||||||
|
int chidNum = SocketUtils.getInstance().childrenIp.length + 1;
|
||||||
|
|
||||||
|
if (num <= chidNum * 10){
|
||||||
|
numController.text = '不能小于${chidNum*10}';
|
||||||
|
ToastUtils.showToast('金额不能太小');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxNum = num ~/ chidNum;
|
||||||
|
SocketUtils.getInstance().sendInpuMessage(maxNum);
|
||||||
|
|
||||||
|
// 本地处理
|
||||||
|
List<int> nums = NumberTool().randomNum(maxNum);
|
||||||
|
widget.controller.executeScript(WindowsJs.inputJs(nums.first));
|
||||||
|
nums.removeAt(0);
|
||||||
|
SynchronizationWebTool.getInstance().input(nums);
|
||||||
|
}catch(e){
|
||||||
|
ToastUtils.showToast('请输入数字');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('填入总金额')),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class _WindowsPageState extends State<WindowsPage> {
|
||||||
|
|
||||||
mainController.loadUrl('http://www.df6831.com/');
|
mainController.loadUrl('http://www.df6831.com/');
|
||||||
|
|
||||||
gridController.addMainController(mainController);
|
gridController.addWebController(mainController);
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
initDone = true;
|
initDone = true;
|
||||||
|
|
@ -61,35 +61,13 @@ class _WindowsPageState extends State<WindowsPage> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
|
if (initDone == false) return Container();
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: WebGridWidget(
|
body: WebGridWidget(
|
||||||
controller: gridController,
|
controller: gridController,
|
||||||
),
|
),
|
||||||
floatingActionButton: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
FloatingActionButton(
|
|
||||||
onPressed: (){
|
|
||||||
gridController.addWeb();
|
|
||||||
},
|
|
||||||
heroTag: 1,
|
|
||||||
tooltip: '添加网页',
|
|
||||||
child: const Icon(Icons.add),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 20,)
|
|
||||||
,
|
|
||||||
FloatingActionButton(
|
|
||||||
onPressed: (){
|
|
||||||
gridController.addAllWeb();
|
|
||||||
},
|
|
||||||
heroTag: 2,
|
|
||||||
tooltip: '添加10个网页',
|
|
||||||
child: const Row(
|
|
||||||
children: [Icon(Icons.add),Text('10')],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue