// ignore_for_file: use_build_context_synchronously import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:share_plus/share_plus.dart'; ui.Rect? shareOriginForContext(BuildContext context) { final renderObject = context.findRenderObject(); if (renderObject is! RenderBox || !renderObject.hasSize) { return null; } return renderObject.localToGlobal(Offset.zero) & renderObject.size; } Future captureWidgetPng( GlobalKey key, { double pixelRatio = 3.0, }) async { await WidgetsBinding.instance.endOfFrame; final context = key.currentContext; if (context == null) { throw StateError('share target is not mounted'); } final renderObject = context.findRenderObject(); if (renderObject is! RenderRepaintBoundary) { throw StateError('share target is not a repaint boundary'); } final image = await renderObject.toImage(pixelRatio: pixelRatio); final byteData = await image.toByteData(format: ui.ImageByteFormat.png); if (byteData == null) { throw StateError('failed to convert share image'); } return byteData.buffer.asUint8List(); } Future sharePngFromBoundary( GlobalKey key, { required String fileName, String? text, String? subject, ui.Rect? sharePositionOrigin, double pixelRatio = 3.0, }) async { final bytes = await captureWidgetPng(key, pixelRatio: pixelRatio); final xFile = XFile.fromData(bytes, mimeType: 'image/png', name: fileName); await SharePlus.instance.share( ShareParams( files: [xFile], text: text, subject: subject, sharePositionOrigin: sharePositionOrigin, ), ); } Future sharePlainText({ required String text, String? subject, ui.Rect? sharePositionOrigin, }) async { await SharePlus.instance.share( ShareParams( text: text, subject: subject, sharePositionOrigin: sharePositionOrigin, ), ); }