qr_code_with_logo.dart 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import 'dart:async';
  2. import 'dart:ui' as ui;
  3. import 'package:fis_lib_qrcode/qr_flutter.dart';
  4. import 'package:fis_lib_qrcode/src/custom_qrcode_builder.dart';
  5. import 'package:fis_ui/index.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:flutter/services.dart';
  8. /// 带logo的二维码
  9. class VQRCodeWithLogo extends StatefulWidget implements FWidget {
  10. /// 二维码数据
  11. final String qrData;
  12. /// 二维码说明
  13. final String? codeStatement;
  14. /// 操作说明
  15. final String? operationStatement;
  16. /// 操作回调
  17. final void Function()? operationSuccessCallback;
  18. /// 尺寸
  19. final double size;
  20. /// logo尺寸
  21. final double? logoSize;
  22. final double titleWidth;
  23. ///带Logo的二维码
  24. const VQRCodeWithLogo(
  25. this.qrData, {
  26. Key? key,
  27. this.codeStatement = "QRCodeStatement",
  28. this.operationStatement = "QRCodeOperationStatement",
  29. this.operationSuccessCallback,
  30. this.size = 280,
  31. this.titleWidth = 160,
  32. this.logoSize,
  33. }) : super(key: key);
  34. @override
  35. _VQRCodeWithLogoState createState() => _VQRCodeWithLogoState();
  36. }
  37. class _VQRCodeWithLogoState extends State<VQRCodeWithLogo> {
  38. @override
  39. Widget build(BuildContext context) {
  40. final qrFutureBuilder = CustomFutureBuilder<ui.Image>(
  41. future: _loadOverlayImage(),
  42. builder: (ctx, snapshot) {
  43. final size = widget.size;
  44. final logoSize = widget.logoSize ?? size / 5;
  45. if (!snapshot.hasData) {
  46. return Container(width: size, height: size);
  47. }
  48. return CustomPaint(
  49. size: Size.square(size),
  50. painter: QrPainter(
  51. data: widget.qrData,
  52. version: QrVersions.auto,
  53. eyeStyle: const QrEyeStyle(
  54. eyeShape: QrEyeShape.square,
  55. color: Colors.black,
  56. ),
  57. dataModuleStyle: const QrDataModuleStyle(
  58. dataModuleShape: QrDataModuleShape.square,
  59. color: Colors.black,
  60. ),
  61. embeddedImage: snapshot.data,
  62. embeddedImageStyle: QrEmbeddedImageStyle(
  63. size: Size.square(logoSize),
  64. ),
  65. ),
  66. );
  67. },
  68. );
  69. return Material(
  70. color: Colors.white,
  71. child: FContainer(
  72. width: widget.titleWidth,
  73. child: FColumn(
  74. mainAxisAlignment: MainAxisAlignment.center,
  75. children: [
  76. qrFutureBuilder,
  77. FPadding(
  78. padding: EdgeInsets.symmetric(
  79. vertical: 8,
  80. horizontal: 8,
  81. ).copyWith(
  82. bottom: 5,
  83. ),
  84. child: FText(
  85. widget.codeStatement!,
  86. overflow: TextOverflow.ellipsis,
  87. ),
  88. ),
  89. FInk(
  90. decoration: UnderlineTabIndicator(
  91. borderSide: BorderSide(color: Colors.blue),
  92. insets: EdgeInsets.fromLTRB(0, 0, 0, 1)),
  93. child: FInkWell(
  94. child: FText(
  95. widget.operationStatement!,
  96. style: TextStyle(color: Colors.blue),
  97. ),
  98. onTap: () => {
  99. Clipboard.setData(ClipboardData(text: widget.qrData)),
  100. widget.operationSuccessCallback?.call()
  101. },
  102. ),
  103. )
  104. ],
  105. ),
  106. ),
  107. );
  108. }
  109. Future<ui.Image> _loadOverlayImage() async {
  110. final completer = Completer<ui.Image>();
  111. final byteData = await rootBundle.load('assets/images/flyinsono.png');
  112. ui.decodeImageFromList(byteData.buffer.asUint8List(), completer.complete);
  113. return completer.future;
  114. }
  115. }