Last active
June 24, 2019 20:10
-
-
Save lukepighetti/3a3325a74f50567b2b4f83e7e102849b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* QR.Flutter | |
* Copyright (c) 2019 the QR.Flutter authors. | |
* See LICENSE for distribution and usage details. | |
*/ | |
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/widgets.dart'; | |
import 'package:qr/qr.dart'; | |
import 'painter.dart'; | |
typedef ErrorBuilder = Widget Function(BuildContext context, dynamic error); | |
class QrImage extends StatelessWidget { | |
final String data; | |
final ErrorBuilder errorBuilder; | |
final Color foregroundColor; | |
final Color backgroundColor; | |
final EdgeInsets padding; | |
final double size; | |
final bool gapless; | |
final int version; | |
final int errorCorrectionLevel; | |
QrImage({ | |
@required this.data, | |
this.errorBuilder, | |
Key key, | |
this.size, | |
this.padding = const EdgeInsets.all(10.0), | |
this.backgroundColor, | |
this.foregroundColor = const Color(0xFF000000), | |
this.version = 4, | |
this.errorCorrectionLevel = QrErrorCorrectLevel.L, | |
this.gapless = true, | |
}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
final qr = QrCode(version, errorCorrectionLevel); | |
bool hasError = false; | |
dynamic error; | |
try { | |
qr.addData(data); | |
qr.make(); | |
hasError = false; | |
} catch (e) { | |
hasError = true; | |
error = e; | |
} | |
return LayoutBuilder( | |
builder: (BuildContext context, BoxConstraints constraints) { | |
final double widgetSize = size ?? constraints.biggest.shortestSide; | |
return Container( | |
width: widgetSize, | |
height: widgetSize, | |
color: backgroundColor, | |
child: Padding( | |
padding: padding, | |
child: hasError | |
? errorBuilder(context, error) | |
: CustomPaint( | |
painter: QrPainter( | |
qr: qr, | |
color: foregroundColor, | |
gapless: gapless, | |
), | |
), | |
), | |
); | |
}, | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'image.dart' show QrImage; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Sandbox', | |
home: Scaffold( | |
body: SafeArea( | |
child: Center( | |
child: _Home(), | |
), | |
), | |
), | |
); | |
} | |
} | |
class _Home extends StatefulWidget { | |
@override | |
__HomeState createState() => __HomeState(); | |
} | |
class __HomeState extends State<_Home> { | |
bool hasError = false; | |
_toggleError() { | |
setState(() { | |
hasError = !hasError; | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
print(hasError); | |
return Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
QrImage( | |
data: !hasError | |
? "yo" | |
: "yo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79f", | |
size: 128, | |
errorBuilder: (_, e) => Text("error! $e"), | |
), | |
RaisedButton( | |
onPressed: _toggleError, | |
child: Text("Toggle error"), | |
) | |
], | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* QR.Flutter | |
* Copyright (c) 2019 the QR.Flutter authors. | |
* See LICENSE for distribution and usage details. | |
*/ | |
import 'dart:async'; | |
import 'dart:ui' as ui; | |
import 'package:flutter/services.dart'; | |
import 'package:flutter/widgets.dart'; | |
import 'package:qr/qr.dart'; | |
typedef QrError = void Function(dynamic error); | |
class QrPainter extends CustomPainter { | |
QrPainter({ | |
@required this.qr, | |
this.color = const Color(0xff000000), | |
this.emptyColor, | |
this.gapless = false, | |
}); | |
final Color color; // the color of the dark squares | |
final Color emptyColor; // the other color | |
final bool gapless; | |
final QrCode qr; // our qr code data | |
final Paint _paint = Paint()..style = PaintingStyle.fill; | |
QrCode get _qr => qr; | |
@override | |
void paint(Canvas canvas, Size size) { | |
assert(size.shortestSide != 0, | |
"[QR] WARN: width or height is zero. You should set a 'size' value or nest this painter in a Widget that defines a non-zero size"); | |
if (emptyColor != null) { | |
canvas.drawColor(emptyColor, BlendMode.color); | |
} | |
final double squareSize = size.shortestSide / _qr.moduleCount.toDouble(); | |
final int pxAdjustValue = gapless ? 1 : 0; | |
for (int x = 0; x < _qr.moduleCount; x++) { | |
for (int y = 0; y < _qr.moduleCount; y++) { | |
if (_qr.isDark(y, x)) { | |
final Rect squareRect = Rect.fromLTWH(x * squareSize, y * squareSize, | |
squareSize + pxAdjustValue, squareSize + pxAdjustValue); | |
canvas.drawRect(squareRect, _paint); | |
} | |
} | |
} | |
} | |
@override | |
bool shouldRepaint(CustomPainter oldDelegate) { | |
if (oldDelegate is QrPainter) { | |
return color != oldDelegate.color || _qr != oldDelegate._qr; | |
} | |
return false; | |
} | |
ui.Picture toPicture(double size) { | |
final ui.PictureRecorder recorder = ui.PictureRecorder(); | |
final Canvas canvas = Canvas(recorder); | |
paint(canvas, Size(size, size)); | |
return recorder.endRecording(); | |
} | |
Future<ByteData> toImageData(double size, | |
{ui.ImageByteFormat format = ui.ImageByteFormat.png}) async { | |
final ui.Image uiImage = | |
await toPicture(size).toImage(size.toInt(), size.toInt()); | |
return await uiImage.toByteData(format: format); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment