Flutter ile QR Code Okuyucu

Ayseleynavuz
5 min readJul 13, 2023

--

Qr Code Nedir?

Bir verinin kare şekildeki bir koda gömülmüş halidir. Kodun köşelerinde bulunan kareler kodun pozisyonunu belirlerken kodun kalan kısmı veridir. Telefon kamerası veya kod tarayıcı kullanılarak kod çözümlenerek ve istenen veri kodu taratan kişiye iletilir.

Gerekli paketler

Flutter geliştiricileri tarafından 11 ay önce yayınlanmış olan “qr_code_scanner” paketini kullanacağım.

Adım 1- Projeyi Oluşturma

terminal ekranına flutter create qr_code_reader diyerek bir proje oluşturalım. Sağda görünen dosya yapısını otomatik olarak oluşturuluyor.

Adım 2 Paketlerin Eklenmesi

QR kodu okumak için hazırda bulunan bir Flutter paketi kullanacağız. Bu paketin adı qr_code_scanner'dır. pubspec.yaml dosyasını açın ve dependencies bölümüne aşağıdaki satırları ekleyin:

dependencies:
qr_code_scanner: ^1.0.1

Bu, projenize qr_code_scanner paketini ekleyecektir. Paketin versiyon numarası olarak ^1.0.1 belirtildiği için, en son 1.x.x sürümünü veya 1.0.1 sürümünü kullanacaktır. Projeyi çalıştırdığınızda, paketin en son kararlı sürümü otomatik olarak indirilecektir.

Daha sonra, terminalde projenizin ana dizinine gidin ve aşağıdaki komutu çalıştırarak paketleri projenize indirin:

flutter pub get

Bu komut, projenizde kullanacağınız tüm paketleri indirir.

Android- app -build.gradle dosyasına

defaultConfig kısmına minSdkVersion 20 olacak şekilde düzeltin.

Adım 3 Ana Ekranın Tasarımı

Projenizin ana ekranını tasarlamak için lib/main.dart dosyasını açın. Varsayılan olarak oluşturulan kodu temizleyin ve aşağıdaki kodu ekleyin:

import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:flutter/services.dart';

void main() => runApp(QRCodeReaderApp());

class QRCodeReaderApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'QR Code Reader',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: QRCodeReaderPage(),
);
}
}

class QRCodeReaderPage extends StatefulWidget {
@override
_QRCodeReaderPageState createState() => _QRCodeReaderPageState();
}

class _QRCodeReaderPageState extends State<QRCodeReaderPage> {
late QRViewController _controller;
final GlobalKey _qrKey = GlobalKey();
bool _isQRScanned = false;
String _scannedCode = '';
bool _isFlashOn = false;

@override
void dispose() {
_controller?.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR Code Reader'),
),
body: Stack(
children: [
_buildQrView(context),
Align(
alignment: Alignment.center,
child: Container(
width: 200,
height: 200,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 2.0,
),
),
),
),
_isQRScanned ? _buildScannedCode() : Container(),
],
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => _toggleFlash(),
child: Icon(_isFlashOn ? Icons.flash_off : Icons.flash_on),
),
SizedBox(height: 70),
],
),
);
}

Widget _buildQrView(BuildContext context) {
return QRView(
key: _qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.blue,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 220,
),
);
}

Widget _buildScannedCode() {
return Positioned(
bottom: 20,
left: 0,
right: 0,
child: Center(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'Scanned Code: $_scannedCode',
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
);
}

void _onQRViewCreated(QRViewController controller) {
setState(() {
_controller = controller;
});
_controller.scannedDataStream.listen((scanData) {
setState(() {
_isQRScanned = true;
_scannedCode = scanData.code!;
});
});
}

void _toggleFlash() {
setState(() {
_isFlashOn = !_isFlashOn;
});

_controller.toggleFlash();
}
}

Daha sonra emülatör seçerek çalıştırın ve run- start debugging diyerek uygulamayı başlatın.

Genel olarak görüntüsü alttaki gibidir. Sağ altta el feneri yer almakta ve en altta qr için bağlantı linki oluşmaktadır. Test etmek için kendi telefonumu da bağladım. Bilgisayar üzerinden hazır bir qr kodu açarak (https://tr.wikipedia.org/wiki/QR_kodu) çalışıp çalışmadığını kontrol ettim.

Aşağıda ekran görüntüsü yer almaktadır:

Son olarak pub dev ‘de yer alan hazır örneği çalıştırarak nasıl bir sonuç verdiğine bakalım isterseniz.

example/lib/main.dart

import 'dart:developer';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';

void main() => runApp(const MaterialApp(home: MyHome()));

class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Demo Home Page')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const QRViewExample(),
));
},
child: const Text('qrView'),
),
),
);
}
}

class QRViewExample extends StatefulWidget {
const QRViewExample({Key? key}) : super(key: key);

@override
State<StatefulWidget> createState() => _QRViewExampleState();
}

class _QRViewExampleState extends State<QRViewExample> {
Barcode? result;
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');

// In order to get hot reload to work we need to pause the camera if the platform
// is android, or resume the camera if the platform is iOS.
@override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (result != null)
Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
else
const Text('Scan a code'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return Text('Flash: ${snapshot.data}');
},
)),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Text(
'Camera facing ${describeEnum(snapshot.data!)}');
} else {
return const Text('loading');
}
},
)),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.pauseCamera();
},
child: const Text('pause',
style: TextStyle(fontSize: 20)),
),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.resumeCamera();
},
child: const Text('resume',
style: TextStyle(fontSize: 20)),
),
)
],
),
],
),
),
)
],
),
);
}

Widget _buildQrView(BuildContext context) {
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}

void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
});
}

void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('no Permission')),
);
}
}

@override
void dispose() {
controller?.dispose();
super.dispose();
}
}

Bu yazı da flutter da qr_code_scanner paketini kullanarak basit bir qr code okuyucu tasarlandı. Umarım faydalı olmuştur.

Kaynak Kod:

https://github.com/ayseleynavuz/qr-code-reader

--

--

Ayseleynavuz

Hi, i am software engineer. I write about software development and anything else that comes to mind Full-stack.