import 'dart:io'; import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:path_provider/path_provider.dart'; import 'package:sport/bean/jog/detail.dart'; import 'package:sport/pages/home/home_info_page.dart'; import 'package:sport/pages/run/run_share_long.dart'; import 'package:sport/pages/run/run_share_simple.dart'; import 'package:sport/utils/toast.dart'; import 'package:sport/widgets/appbar.dart'; import 'package:sport/widgets/button_primary.dart'; import 'package:sport/widgets/dialog/request_dialog.dart'; import 'package:sport/widgets/menu_share_bottom.dart'; class RunShare extends StatefulWidget { final JogDetail detail; final File map; const RunShare({Key? key, required this.detail, required this.map}) : super(key: key); @override State createState() { return _PageState(); } } class _PageState extends State with SingleTickerProviderStateMixin { GlobalKey repaintKeySimple = GlobalKey(); GlobalKey repaintKeyLong = GlobalKey(); late TabController _controller; int index = 0; @override void initState() { _controller = TabController(length: 2, vsync: this) ..addListener(() { index = _controller.animation?.value.toInt() ?? 0; }); super.initState(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: buildAppBar(context, title: "运动分享"), body: DefaultTabController( length: 2, child: Column( children: [ Padding( padding: const EdgeInsets.all(12.0), child: indexTabBar(["图片", "长图"], tabController: _controller, fontSize: 14.0, padding: 0.0), ), Expanded( child: TabBarView( controller: _controller, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0), child: RunShareSimple( detail: widget.detail, map: widget.map, repaintWidgetKey: repaintKeySimple, ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 12.0), child: RunShareLongPage( detail: widget.detail, map: widget.map, repaintWidgetKey: repaintKeyLong, ), ), ], )), Padding( padding: const EdgeInsets.all(12.0), child: Row( children: [ Expanded( child: GestureDetector( onTap: () { runShare(context, index, index == 0 ? repaintKeySimple : repaintKeyLong, true); }, child: Container( height: 44, decoration: BoxDecoration(border: Border.all(color: Theme.of(context).accentColor, width: 1), borderRadius: BorderRadius.circular(50)), child: Center( child: Text( "保存", style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Theme.of(context).accentColor, fontSize: 16.0), strutStyle: StrutStyle(height: 1.1), ), ), ), )), const SizedBox( width: 20.0, ), Expanded( child: PrimaryButton( height: 44.0, callback: () { runShare(context, index, index == 0 ? repaintKeySimple : repaintKeyLong, false); }, content: "分享", )), ], ), ), ], ), ), ); } } _takePicture(int index, GlobalKey key) async { try { RenderObject? boundary = key.currentContext?.findRenderObject(); if (!(boundary is RenderRepaintBoundary)) return; double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比 ui.Image image = await boundary.toImage(pixelRatio: dpr); ui.PictureRecorder pictureRecorder = new ui.PictureRecorder(); // 图片记录仪 Canvas canvas = new Canvas(pictureRecorder); //canvas接受一个图片 canvas.drawColor(Colors.white, BlendMode.clear); Paint _paint = new Paint()..isAntiAlias = true; canvas.drawImage(image, Offset(0, 0), _paint); ui.Image picture = await pictureRecorder.endRecording().toImage(image.width, image.height); //设置生成图片的宽和高 ByteData? pngImageBytes = await picture.toByteData(format: ui.ImageByteFormat.png); if (pngImageBytes == null) return; Uint8List pngBytes = pngImageBytes.buffer.asUint8List(); String sTempDir = (await getTemporaryDirectory()).path; bool isDirExist = await Directory(sTempDir).exists(); if (!isDirExist) { Directory(sTempDir).create(); } File file = await File(sTempDir + "/poster-temp-${DateTime.now().millisecondsSinceEpoch}.png").writeAsBytes(pngBytes.buffer.asUint8List()); print("save file $file"); return file.path; } catch (e) { print(e); } return null; } runShare(BuildContext context, int index, GlobalKey key, bool save, {bool app = false}) async { var path = await request(context, () async { return await _takePicture(index, key); }); if (path == null) return; print("share path $path"); if (save) { final result = await ImageGallerySaver.saveFile(path); if (result != null && result["isSuccess"] == true) ToastUtil.show("已保存至相册"); } else { await showModalBottomSheet( context: context, backgroundColor: Colors.white, elevation: 10, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), builder: (context) => MenuShareBottomContent( "Img", hasDownload: false, file: path, app: app, ), ); } }