LoginSignup
2
3

More than 1 year has passed since last update.

FlutterでQRコードを読み込む(riverpod 2)

Last updated at Posted at 2022-12-22

はじめに

QRコードを読み取るアプリを作る機会があったので、ライブラリを探っていたら qr_code_scanner っていう良さげなものがあったので、使わせていただきました。
exampleが StatefulWidget で書かれていたのですが、riverpodを使っていたので書き換えたバージョンを紹介します。
カメラ権限周りの記述については割愛しています。

環境

% fvm flutter --version
Flutter 3.3.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision d9111f6402 (9 weeks ago) • 2022-10-19 12:27:13 -0700
Engine • revision 3ad69d7be3
Tools • Dart 2.18.2 • DevTools 2.15.0

ソース

dart@pubspec.yaml
environment:
  sdk: '>=2.18.2 <3.0.0'

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations: 
    sdk: flutter

  flutter_riverpod: ^2.0.2
  qr_code_scanner: ^1.0.1
dart@qr_code_reader_page.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';

final qrCodeProvider =
    StateNotifierProvider.autoDispose<QRCodeNotifier, Barcode>((ref) {
  final notifier = QRCodeNotifier();
  ref.onDispose(() => notifier.controller?.dispose());
  return notifier;
});

class QRCodeNotifier extends StateNotifier<Barcode> {
  QRViewController? controller;
  QRCodeNotifier() : super(Barcode(null, BarcodeFormat.unknown, null));

  void onQRViewCreated(QRViewController controller) {
    this.controller = controller;
    this.controller!.scannedDataStream.listen((scanData) {
      state = scanData;
    });
  }
}

class QRCodeReaderPage extends ConsumerWidget {
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');

  QRCodeReaderPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final notifier = ref.watch(qrCodeProvider.notifier);
    final state = ref.watch(qrCodeProvider);
    final double scanArea = (MediaQuery.of(context).size.width < 400 ||
            MediaQuery.of(context).size.height < 400)
        ? 150.0
        : 300.0;
    return Scaffold(
      body: Column(
        children: [
          Expanded(
              flex: 4,
              child: QRView(
                key: qrKey,
                onQRViewCreated: notifier.onQRViewCreated,
                overlay: QrScannerOverlayShape(
                    borderColor: Colors.red,
                    borderRadius: 10,
                    borderLength: 30,
                    borderWidth: 10,
                    cutOutSize: scanArea),
                onPermissionSet: (ctrl, p) =>
                    _onPermissionSet(context, ctrl, p),
              )),
          Expanded(
              flex: 1,
              child: FittedBox(
                fit: BoxFit.contain,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    if (state.format != BarcodeFormat.unknown)
                      Text(
                          'Barcode Type: ${describeEnum(state.format)}   Data: ${state.code}')
                    else
                      const Text('Scan a code'),
                  ],
                ),
              ))
        ],
      ),
    );
  }

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

最近主流?になりつつある riverpod ですが、私のように書き方に苦労している人がいると思ったので紹介してみました。
必要最低限のコードですが、何かの役に立てば幸いです。

2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3