From e5251a694ca789e4f7e7d2c7996c3e021a2c6976 Mon Sep 17 00:00:00 2001 From: toly <1981462002@qq.com> Date: Tue, 11 Aug 2020 12:59:31 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E6=9B=B4=E6=96=B0flutter=20unit?= =?UTF-8?q?=20mac=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/flutter.db | Bin 774144 -> 778240 bytes .../RepaintBoundary/node1_base.dart | 182 ++++++++++++++++++ .../RepaintBoundary/node2_save.dart | 68 +++++++ lib/views/widgets/exp/render_object_unit.dart | 2 + lib/views/widgets/widgets_map.dart | 5 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Podfile.lock | 11 ++ pubspec.lock | 58 +++++- pubspec.yaml | 1 + 9 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node1_base.dart create mode 100644 lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node2_save.dart diff --git a/assets/flutter.db b/assets/flutter.db index c18522c67df3504035f57ebe98eba2125ca48d57..56ffbbd684b23c618e220de8d82032b762ce6960 100644 GIT binary patch delta 7753 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 delta 5840 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 O96@KmJO5$zV*dla`)H&9 diff --git a/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node1_base.dart b/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node1_base.dart new file mode 100644 index 0000000..2cf57af --- /dev/null +++ b/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node1_base.dart @@ -0,0 +1,182 @@ +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2020/7/22 +/// contact me by email 1981462002@qq.com +/// 说明: 264 RepaintBoundary 重绘边界 为子组件创建一个单独的显示列表,提升性能。源码中在TextField、DrawerController、Scrollbar、Sliver等组件中均有应用。 +// { +// "widgetId": 264, +// "name": "RepaintBoundary基本使用", +// "priority": 1, +// "subtitle": "【child】 : 子组件 【Widget】\n" +// "比如上面的绘制视图,即使shouldRepaint为false,在滑动中会也会不断执行paint方法,使用RepaintBoundary可以避免不必要的绘制。", +// } + +class RepaintBoundaryDemo extends StatelessWidget{ + @override + Widget build(BuildContext context) { + return RepaintBoundary( + child: TempPlayBezier3Page(), + ); + } +} + +class TempPlayBezier3Page extends StatefulWidget { + @override + _TempPlayBezier3PageState createState() => _TempPlayBezier3PageState(); +} + +class _TempPlayBezier3PageState extends State { + List _pos = []; + int selectPos; + + @override + void initState() { + _initPoints(); + super.initState(); + } + + void _initPoints() { + _pos = List(); + _pos.add(Offset(0, 0)); + _pos.add(Offset(60, -60)); + _pos.add(Offset(-90, -90)); + _pos.add(Offset(-120, -40)); + } + + @override + Widget build(BuildContext context) { + return Container( + height: 200, + width: MediaQuery.of(context).size.width, + child: CustomPaint( + painter: TempBezierPainter(pos: _pos, selectPos: selectPos), + ), + ); + } +} + +class TempBezierPainter extends CustomPainter { + Paint _gridPaint; + Path _gridPath; + + Paint _mainPaint; + Path _mainPath; + int selectPos; + Paint _helpPaint; + + List pos; + + TempBezierPainter({this.pos, this.selectPos}) { + _gridPaint = Paint()..style = PaintingStyle.stroke; + _gridPath = Path(); + + _mainPaint = Paint() + ..color = Colors.orange + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + _mainPath = Path(); + + _helpPaint = Paint() + ..color = Colors.purple + ..style = PaintingStyle.stroke + ..strokeWidth = 2 + ..strokeCap = StrokeCap.round; + } + + @override + void paint(Canvas canvas, Size size) { + print('----------Paint-------'); + canvas.clipRect(Offset.zero & size); + canvas.translate(size.width / 2, size.height / 2); + _drawGrid(canvas, size); //绘制格线 + _drawAxis(canvas, size); //绘制轴线 + + _mainPath.moveTo(pos[0].dx, pos[0].dy); + _mainPath.cubicTo( + pos[1].dx, pos[1].dy, pos[2].dx, pos[2].dy, pos[3].dx, pos[3].dy); + canvas.drawPath(_mainPath, _mainPaint); + _drawHelp(canvas); + _drawSelectPos(canvas); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; + + void _drawGrid(Canvas canvas, Size size) { + _gridPaint + ..color = Colors.grey + ..strokeWidth = 0.5; + _gridPath = _buildGridPath(_gridPath, size); + canvas.drawPath(_buildGridPath(_gridPath, size), _gridPaint); + + canvas.save(); + canvas.scale(1, -1); //沿x轴镜像 + canvas.drawPath(_gridPath, _gridPaint); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, 1); //沿y轴镜像 + canvas.drawPath(_gridPath, _gridPaint); + canvas.restore(); + + canvas.save(); + canvas.scale(-1, -1); //沿原点镜像 + canvas.drawPath(_gridPath, _gridPaint); + canvas.restore(); + } + + void _drawAxis(Canvas canvas, Size size) { + canvas.drawPoints( + PointMode.lines, + [ + Offset(-size.width / 2, 0), + Offset(size.width / 2, 0), + Offset(0, -size.height / 2), + Offset(0, size.height / 2), + Offset(0, size.height / 2), + Offset(0 - 7.0, size.height / 2 - 10), + Offset(0, size.height / 2), + Offset(0 + 7.0, size.height / 2 - 10), + Offset(size.width / 2, 0), + Offset(size.width / 2 - 10, 7), + Offset(size.width / 2, 0), + Offset(size.width / 2 - 10, -7), + ], + _gridPaint + ..color = Colors.blue + ..strokeWidth = 1.5); + } + + Path _buildGridPath(Path path, Size size, {step = 20.0}) { + for (int i = 0; i < size.height / 2 / step; i++) { + path.moveTo(0, step * i); + path.relativeLineTo(size.width / 2, 0); + } + for (int i = 0; i < size.width / 2 / step; i++) { + path.moveTo(step * i, 0); + path.relativeLineTo( + 0, + size.height / 2, + ); + } + return path; + } + + void _drawHelp(Canvas canvas) { + canvas.drawPoints(PointMode.lines, pos, _helpPaint..strokeWidth = 1); + canvas.drawPoints(PointMode.points, pos, _helpPaint..strokeWidth = 8); + } + + void _drawSelectPos(Canvas canvas) { + if (selectPos == null) return; + canvas.drawCircle( + pos[selectPos], + 10, + _helpPaint + ..color = Colors.green + ..strokeWidth = 2); + } +} diff --git a/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node2_save.dart b/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node2_save.dart new file mode 100644 index 0000000..7d700f2 --- /dev/null +++ b/lib/views/widgets/SingleChildRenderObjectWidget/RepaintBoundary/node2_save.dart @@ -0,0 +1,68 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:ui' as ui; +import 'node1_base.dart'; + +/// create by 张风捷特烈 on 2020/7/22 +/// contact me by email 1981462002@qq.com +/// 说明: +// { +// "widgetId": 264, +// "name": "保存Widget成为图片", +// "priority": 2, +// "subtitle": "通过RenderRepaintBoundary可以获取子组件的Image信息,从而获取字节保存为图片文件。", +// } + +class RepaintBoundarySave extends StatelessWidget { + final GlobalKey _globalKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + RepaintBoundary( + key: _globalKey, + child: TempPlayBezier3Page(), + ), + Positioned(right: -10, child: _buildButton3(context)) + ], + ); + } + + Widget _buildButton3(context) => MaterialButton( + child: Icon( + Icons.save_alt, + size: 15, + color: Colors.white, + ), + color: Colors.green, + shape: CircleBorder( + side: BorderSide(width: 2.0, color: Color(0xFFFFDFDFDF)), + ), + onPressed: () async { + var bits = await _widget2Image(_globalKey); + var dir = await getApplicationSupportDirectory(); + var file = File(dir.path + "/save_img.png"); + var f = await file.writeAsBytes(bits); + Scaffold.of(context).showSnackBar(SnackBar( + backgroundColor: Theme.of(context).primaryColor, + content: Text('保存成功后! 路径为:${f.path}'), + )); + }); + + Future _widget2Image(GlobalKey key) async { + RenderRepaintBoundary boundary = key.currentContext.findRenderObject(); + //获得 ui.image + ui.Image img = await boundary.toImage(); + //获取图片字节 + var byteData = await img.toByteData(format: ui.ImageByteFormat.png); + Uint8List bits = byteData.buffer.asUint8List(); + return bits; + } +} diff --git a/lib/views/widgets/exp/render_object_unit.dart b/lib/views/widgets/exp/render_object_unit.dart index 3197d96..b18d292 100644 --- a/lib/views/widgets/exp/render_object_unit.dart +++ b/lib/views/widgets/exp/render_object_unit.dart @@ -29,6 +29,8 @@ export '../SingleChildRenderObjectWidget/Align/node1_base.dart'; export '../SingleChildRenderObjectWidget/Align/node2_other.dart'; export '../SingleChildRenderObjectWidget/CustomSingleChildLayout/node1_base.dart'; export '../SingleChildRenderObjectWidget/CustomSingleChildLayout/node2_offset.dart'; +export '../SingleChildRenderObjectWidget/RepaintBoundary/node1_base.dart'; +export '../SingleChildRenderObjectWidget/RepaintBoundary/node2_save.dart'; export '../SingleChildRenderObjectWidget/ConstrainedBox/node1_base.dart'; export '../SingleChildRenderObjectWidget/FractionalTranslation/node1_base.dart'; diff --git a/lib/views/widgets/widgets_map.dart b/lib/views/widgets/widgets_map.dart index 9d849db..c876aff 100644 --- a/lib/views/widgets/widgets_map.dart +++ b/lib/views/widgets/widgets_map.dart @@ -149,6 +149,11 @@ class WidgetsMap { CustomVisibility(), ReplacementVisibility(), ]; + case "RepaintBoundary": + return [ + RepaintBoundaryDemo(), + RepaintBoundarySave(), + ]; case "Chip": return [ CustomChip(), diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index affe9be..fd853e1 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,11 +5,13 @@ import FlutterMacOS import Foundation +import path_provider_macos import shared_preferences_macos import sqflite import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 7218929..1ccf80d 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -3,6 +3,9 @@ PODS: - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) + - path_provider (0.0.1) + - path_provider_macos (0.0.1): + - FlutterMacOS - shared_preferences (0.0.1) - shared_preferences_macos (0.0.1): - FlutterMacOS @@ -15,6 +18,8 @@ PODS: DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64`) + - path_provider (from `Flutter/ephemeral/.symlinks/plugins/path_provider/macos`) + - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) - shared_preferences (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences/macos`) - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) @@ -28,6 +33,10 @@ SPEC REPOS: EXTERNAL SOURCES: FlutterMacOS: :path: Flutter/ephemeral/.symlinks/flutter/darwin-x64 + path_provider: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider/macos + path_provider_macos: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos shared_preferences: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences/macos shared_preferences_macos: @@ -42,6 +51,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + path_provider: e0848572d1d38b9a7dd099e79cf83f5b7e2cde9f + path_provider_macos: a0a3fd666cb7cd0448e936fb4abad4052961002b shared_preferences: 9fec34d1bd906196a4da48fcf6c3ad521cc00b8d shared_preferences_macos: 5e5c2839894accb56b7d23328905b757f2bafaf6 sqflite: 6c1f07e1d4399d619ea619fea9171251dd24d058 diff --git a/pubspec.lock b/pubspec.lock index 3c28c02..06b8cc3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -71,6 +71,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.2.1" flutter: dependency: "direct main" description: flutter @@ -135,6 +142,41 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.7.0" + path_provider: + dependency: "direct main" + description: + name: path_provider + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.6.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.1+2" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.4+3" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.2" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.1" plugin_platform_interface: dependency: transitive description: @@ -142,6 +184,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.13" provider: dependency: transitive description: @@ -308,6 +357,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.0.8" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.0" sdks: dart: ">=2.9.0-14.0.dev <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index b3abdb2..474837e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -29,6 +29,7 @@ dependencies: flutter_star: ^0.1.2 # 星星组件 shared_preferences: ^0.5.6+3 # xml 固化 url_launcher: ^5.4.2 # url + path_provider: ^1.6.11 intl: ^0.16.1 # 格式化 share: ^0.6.3+6 dev_dependencies: