Skip to content

Instantly share code, notes, and snippets.

@deshario
Last active July 30, 2024 07:20
Show Gist options
  • Save deshario/7e5968d033c6872b4ddd8d31303d46b8 to your computer and use it in GitHub Desktop.
Save deshario/7e5968d033c6872b4ddd8d31303d46b8 to your computer and use it in GitHub Desktop.
Render QrView in Dialog
import 'package:flutter/material.dart';
import 'package:deshario/components/ScannerOverlay.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QrDialog extends StatefulWidget {
final String dialogTitle;
final ValueChanged<String> onGetResult;
QrDialog({
@required this.dialogTitle,
@required this.onGetResult
});
@override
QrDialogState createState() => QrDialogState();
}
class QrDialogState extends State<QrDialog> {
final GlobalKey mqrKey = GlobalKey(debugLabel: 'mQR');
QRViewController controller;
Widget renderQr(){
return Stack(
children: [
QRView(
key: mqrKey,
overlay: ScannerOverlay(
borderColor: Colors.white,
borderLength: 40,
borderWidth: 5,
cutOutSize: 280
),
onQRViewCreated: _onQRViewCreate),
],
);
}
Dialog dialogContent(mContext){
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(3)),
child: Container(
width: MediaQuery.of(context).size.width * 1,
height: MediaQuery.of(context).size.height * 0.45,
color: Colors.transparent,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Center(
child: Text('${widget.dialogTitle}', style: TextStyle(fontSize: 20)),
),
),
Expanded(
flex: 5,
child: QRView(
key: GlobalKey(debugLabel: 'order.getKey()'),
overlay: ScannerOverlay(
borderColor: Colors.white,
borderLength: 40,
borderWidth: 5,
cutOutSize: 250
),
onQRViewCreated: _onQRViewCreate
),
),
],
)
),
);
}
@override
Widget build(BuildContext context) {
return dialogContent(context);
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
void _onQRViewCreate(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData){
widget.onGetResult(scanData);
});
}
}
import 'dart:ui';
import 'package:flutter/material.dart';
class ScannerOverlay extends ShapeBorder {
final Color borderColor;
final double borderWidth;
final Color overlayColor;
final double borderRadius;
final double borderLength;
final double cutOutSize;
ScannerOverlay({
this.borderColor = Colors.red,
this.borderWidth = 3.0,
this.overlayColor = const Color.fromRGBO(0, 0, 0, 80),
this.borderRadius = 0,
this.borderLength = 40,
this.cutOutSize = 250,
}) : assert(
cutOutSize != null
? cutOutSize != null
? borderLength <= cutOutSize / 2 + borderWidth * 2
: true
: true,
"Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}");
@override
EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10.0);
@override
Path getInnerPath(Rect rect, {TextDirection textDirection}) {
return Path()
..fillType = PathFillType.evenOdd
..addPath(getOuterPath(rect), Offset.zero);
}
@override
Path getOuterPath(Rect rect, {TextDirection textDirection}) {
Path _getLeftTopPath(Rect rect) {
return Path()
..moveTo(rect.left, rect.bottom)
..lineTo(rect.left, rect.top)
..lineTo(rect.right, rect.top);
}
return _getLeftTopPath(rect)
..lineTo(
rect.right,
rect.bottom,
)
..lineTo(
rect.left,
rect.bottom,
)
..lineTo(
rect.left,
rect.top,
);
}
@override
void paint(Canvas canvas, Rect rect, {TextDirection textDirection}) {
final width = rect.width;
final borderWidthSize = width / 2;
final height = rect.height;
final borderOffset = borderWidth / 2;
final _borderLength = borderLength > cutOutSize / 2 + borderWidth * 2
? borderWidthSize / 2
: borderLength;
final _cutOutSize = cutOutSize != null && cutOutSize < width
? cutOutSize
: width - borderOffset;
final backgroundPaint = Paint()
..color = overlayColor
..style = PaintingStyle.fill;
final borderPaint = Paint()
..color = borderColor
..style = PaintingStyle.stroke
..strokeWidth = borderWidth;
final boxPaint = Paint()
..color = borderColor
..style = PaintingStyle.fill
..blendMode = BlendMode.dstOut;
final cutOutRect = Rect.fromLTWH(
rect.left + width / 2 - _cutOutSize / 2 + borderOffset,
rect.top + height / 2 - _cutOutSize / 2 + borderOffset,
_cutOutSize - borderOffset * 2,
_cutOutSize - borderOffset * 2,
);
canvas.saveLayer(
rect,
backgroundPaint,
);
canvas
..drawRect(
rect,
backgroundPaint,
)
// Draw top right corner
..drawRRect(
RRect.fromLTRBAndCorners(
cutOutRect.right - _borderLength,
cutOutRect.top,
cutOutRect.right,
cutOutRect.top + _borderLength,
topRight: Radius.circular(borderRadius),
),
borderPaint,
)
// Draw top left corner
..drawRRect(
RRect.fromLTRBAndCorners(
cutOutRect.left,
cutOutRect.top,
cutOutRect.left + _borderLength,
cutOutRect.top + _borderLength,
topLeft: Radius.circular(borderRadius),
),
borderPaint,
)
// Draw bottom right corner
..drawRRect(
RRect.fromLTRBAndCorners(
cutOutRect.right - _borderLength,
cutOutRect.bottom - _borderLength,
cutOutRect.right,
cutOutRect.bottom,
bottomRight: Radius.circular(borderRadius),
),
borderPaint,
)
// Draw bottom left corner
..drawRRect(
RRect.fromLTRBAndCorners(
cutOutRect.left,
cutOutRect.bottom - _borderLength,
cutOutRect.left + _borderLength,
cutOutRect.bottom,
bottomLeft: Radius.circular(borderRadius),
),
borderPaint,
)
..drawRRect(
RRect.fromRectAndRadius(
cutOutRect,
Radius.circular(borderRadius),
),
boxPaint,
)
..restore();
}
@override
ShapeBorder scale(double t) {
return ScannerOverlay(
borderColor: borderColor,
borderWidth: borderWidth,
overlayColor: overlayColor,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment