juliuscanute / qr_code_scanner

QR Code Scanner for Flutter
BSD 2-Clause "Simplified" License
1.01k stars 783 forks source link

[BUG] qr_code_scanner 1.0.0 - Doesn't scan when open from landscape orientation on Android. #555

Open valera21115 opened 2 years ago

valera21115 commented 2 years ago

I made that the scanner screen must be only in portrait orientation. When navigate to scanner screen from another in landscape mode, scanner doesn't work in any of orientation.

main.dart

import 'package:flutter/material.dart';
import 'package:qr_scanner_bug/scanner.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(title: 'Home page'),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child:ElevatedButton(onPressed: () {Navigator.push(context, MaterialPageRoute(builder: (context) => const ScannerScreen()));},
        child: const Text('Open scanner'))
    ));
  }
}

scanner.dart

import 'dart:io';

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

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

  @override
  State<ScannerScreen> createState() => _ScannerScreenState();
}

class _ScannerScreenState extends State<ScannerScreen> {
  final qrKey = GlobalKey(debugLabel: 'QR');
  QRViewController? _cameraController;
  Barcode? barcode;

  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
  }

  @override
  void dispose() {
    _cameraController?.dispose();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.portraitUp,
    ]);
    super.dispose();
  }

  @override
  void reassemble() {
    super.reassemble();

    if (Platform.isAndroid) {
      _cameraController!.pauseCamera();
    }
    _cameraController!.resumeCamera();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
          body: Stack(
            alignment: Alignment.bottomCenter,
            children: [
              QRView(
                key: qrKey,
                onQRViewCreated: onQRViewCreated,
                overlay: QrScannerOverlayShape(borderRadius:  14)
              ),
              Text(barcode == null ? 'Scan a code' :  barcode!.code!, style: const TextStyle(color: Colors.red, fontSize: 20))
            ],
          ),
        ));
  }

  onQRViewCreated(QRViewController controller) {
    setState(() => _cameraController = controller);
    controller.resumeCamera();
    controller.scannedDataStream.listen((result) {
      setState(() => barcode = result);
    });
  }
}
manavgarg-cardbyte commented 2 years ago

I'm facing the same issue

Miko2x commented 1 year ago

@valera21115 @manavgarg-cardbyte For some reason when entering the page the default controller is pause(). Therefore you have to call controller.resumeCamera(); after onQRViewCreated.

And you don't have to call _cameraController!.pauseCamera(); in reassemble(). Because without using reassemble() I can still use hot reload.