Untitled
unknown
plain_text
9 months ago
6.1 kB
14
Indexable
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
class ScannerPage extends StatefulWidget {
const ScannerPage({super.key});
@override
State<ScannerPage> createState() => _ScannerPageState();
}
class _ScannerPageState extends State<ScannerPage>
with SingleTickerProviderStateMixin {
bool isCameraPaused = false;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
late AnimationController _animationController;
late Animation<double> _animation;
bool _isFlashOn = false;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..repeat(reverse: true);
_animation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
);
}
@override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller?.pauseCamera();
}
controller?.resumeCamera();
}
@override
void dispose() {
controller?.dispose();
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final scanBoxSize = MediaQuery.of(context).size.width * 0.7;
return Scaffold(
appBar: AppBar(
title: Text('Scanner'),
centerTitle: true,
actions: [
IconButton(
icon: Icon(_isFlashOn ? Icons.flash_on : Icons.flash_off),
onPressed: () async {
if (controller != null) {
await controller!.toggleFlash();
bool? flashStatus = await controller!.getFlashStatus();
setState(() {
_isFlashOn = flashStatus ?? false;
});
}
},
),
],
),
body: Stack(
children: [
QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blueAccent,
borderRadius: 12,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanBoxSize,
),
),
Center(
child: SizedBox(
width: scanBoxSize,
height: scanBoxSize,
child: AnimatedBuilder(
animation: _animation,
builder: (context, child) {
return CustomPaint(
painter: ScannerLaserPainter(
animationValue: _animation.value,
),
);
},
),
),
),
// Positioned
],
),
);
}
void _onQRViewCreated(QRViewController controller) async {
setState(() {
this.controller = controller;
});
bool? flashStatus = await controller.getFlashStatus();
setState(() {
_isFlashOn = flashStatus ?? false;
});
controller.scannedDataStream.listen((scanData) {
if (mounted && result == null) {
controller.pauseCamera();
_animationController.stop();
setState(() {
result = scanData;
});
Future.delayed(const Duration(seconds: 1), () {
if (mounted) {
context.pushReplacementNamed(
'detail_inventory_barcode',
extra: scanData.code!,
);
// _showSuccessDialog(context, scanData.code!);
}
});
}
});
}
}
class ScannerLaserPainter extends CustomPainter {
final double animationValue;
ScannerLaserPainter({required this.animationValue});
@override
void paint(Canvas canvas, Size size) {
final laserY = size.height * animationValue;
const laserHeight = 60.0;
final Rect rect = Rect.fromLTWH(
0,
laserY - laserHeight / 2,
size.width,
laserHeight,
);
final gradient = LinearGradient(
colors: [Colors.transparent, Colors.blueAccent, Colors.transparent],
stops: const [0.0, 0.5, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
);
final paint = Paint()..shader = gradient.createShader(rect);
canvas.drawRect(rect, paint);
}
@override
bool shouldRepaint(covariant ScannerLaserPainter oldDelegate) {
return oldDelegate.animationValue != animationValue;
}
}
void _showSuccessDialog(BuildContext context, String code) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 32, bottom: 20),
// child: Assets.icons.success.svg(height: 100),
child: Icon(Icons.check_circle, color: Colors.green, size: 100),
),
Text(
'Selamat!',
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
),
const SizedBox(height: 8),
Text(
'Anda telah berhasil melakukan presensi matakuliah Algoritma $code.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black54),
),
],
),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(
// builder: (context) => const TemplateMhsPage(),
// ),
// (Route<dynamic> route) => false,
// );
},
),
],
);
},
);
}
Editor is loading...
Leave a Comment