import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:get/get.dart'; import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart'; import 'package:loopin/IM/controller/im_user_info_controller.dart'; import 'package:loopin/IM/im_friend_listeners.dart'; import 'package:loopin/components/my_toast.dart'; import 'package:loopin/styles/index.dart'; import 'package:loopin/utils/scan_code_type.dart'; import 'package:pretty_qr_code/pretty_qr_code.dart'; class MyQrcode extends StatelessWidget { MyQrcode({ super.key, this.prefix, this.text, }); final String? prefix; final String? text; final controller = Get.find(); // GlobalKey 用于截图 Widget final GlobalKey _qrKey = GlobalKey(); /// 将 Widget 渲染为 Uint8List Future capturePng(BuildContext context) async { try { final boundary = _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary?; if (boundary == null) return null; // final image = await boundary.toImage(pixelRatio: ui.window.devicePixelRatio); final pixelRatio = View.of(context).devicePixelRatio; final image = await boundary.toImage(pixelRatio: pixelRatio); final byteData = await image.toByteData(format: ui.ImageByteFormat.png); return byteData?.buffer.asUint8List(); } catch (e) { logger.e("截图失败: $e"); } return null; } /// 保存二维码到相册 Future saveQrToGallery() async { logger.w('长安了'); final pngBytes = await capturePng(Get.context!); if (pngBytes == null) return; final result = await ImageGallerySaverPlus.saveImage( pngBytes, quality: 100, name: "my_qr_${DateTime.now().millisecondsSinceEpoch}", ); logger.w("保存结果: $result"); MyToast().tip( title: '图片已保存', position: 'top', type: 'success', ); } @override Widget build(BuildContext context) { final userID = controller.userID.value; final faceUrl = controller.faceUrl.value; ImageProvider face; if (faceUrl.isEmpty) { face = AssetImage('assets/images/logo/logo.png'); } else { face = CachedNetworkImageProvider(faceUrl); } final data = '${prefix ?? QrTypeCode.hym}$userID'; return GestureDetector( onLongPress: () { showModalBottomSheet( context: Get.context!, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(16)), ), builder: (context) { return SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: const Icon(Icons.save, color: Colors.black), title: const Text('保存到相册', style: TextStyle(color: Colors.black)), onTap: () async { await saveQrToGallery(); Get.back(); }, ), ], ), ); }, ); }, child: Center( child: Container( alignment: Alignment.topCenter, decoration: const BoxDecoration( color: Colors.transparent, ), child: RepaintBoundary( key: _qrKey, child: Column( mainAxisSize: MainAxisSize.min, // 根据内容高度自适应 children: [ PrettyQrView.data( errorCorrectLevel: QrErrorCorrectLevel.H, data: data, // 二维码内容 decoration: PrettyQrDecoration( background: Colors.transparent, shape: const PrettyQrShape.custom( PrettyQrSmoothSymbol(color: FStyle.primaryColor), finderPattern: PrettyQrSmoothSymbol(color: FStyle.primaryColor), alignmentPatterns: PrettyQrSmoothSymbol(color: FStyle.primaryColor), ), image: PrettyQrDecorationImage( image: face, scale: 0.3, opacity: 1, padding: const EdgeInsets.all(8.0), ), quietZone: const PrettyQrQuietZone.modules(2), ), ), if (text != null && text!.trim().isNotEmpty) ...[ const SizedBox(height: 4), Text( text!, style: const TextStyle( fontSize: 14, color: Colors.grey, ), ), const SizedBox(height: 4), ], ], ), ), ), ), ); } }