Flutter如何将数据从qr_code_scanner传递回上一页并保留上下文

rkkpypqq  于 2023-03-09  发布在  Flutter
关注(0)|答案(1)|浏览(142)

我正在尝试将qr_code_scanner添加到flutter项目中。
我需要做的是按下MainPage上的“扫描”按钮,打开QRScanner页面,然后将结果传递回TextEditingController中的MainPage
我设法做到了这一切。但是,当我将QR扫描结果传递回MainPage时,我将替换整个MainPage上下文。我还将重置所有其他控制器的值。
所以一旦我最终做了Navigator.pop(context);,我就被重定向回QRScanner,页面而不是 Jmeter 板,这是我需要做的。
我的问题是,如何在不替换MainPage上下文的情况下将QR扫描结果传递回来?(至少我认为这是问题所在)。
主页:

class MainPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _MainPageState();
}

class _MainPageState extends State<MainPage> {
  late Store<AppState> store;
  final TextEditingController _name = new TextEditingController();
  late final TextEditingController _qrText = new TextEditingController();

  late QRScan? args;

  @override
  initState() {
    super.initState();

    //In order to use the ModalRoute.of(context)?.settings.arguments outside build method
    final widgetsBinding = WidgetsBinding.instance;
    widgetsBinding.addPostFrameCallback((callback) async {
      if (ModalRoute.of(context)?.settings.arguments != null) {
        args = ModalRoute.of(context)!.settings.arguments as QRScan?;
        _qrText.text = args!.result!;
      }
    });
  }

  void nextButton() async {
    String name = _name.text;
    String uniqueId = _qrText.text;

    final response = await http.get(Uri.parse('url' ));

    if (response.statusCode == 200) {
      //Do something
      Navigator.pop(context); //Here I get redirected back to /qrScanner Page instead of the Dashboard    
    } else {
      //Throw error message
    }
  }

  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, StoreModel>(
        onInit: (str) => str.dispatch({ store = str, }),
        converter: (Store<AppState> store) => StoreModel.create(store),
        builder: (BuildContext context, StoreModel storeModel) => SafeArea(
            child: Scaffold(
              appBar: new AppBar(),
              body: new Container(
                  child: ListView(shrinkWrap: true, children: <Widget>[
                    new Column(
                      children: <Widget>[
                        _buildTextFields()
                      ],
                    )
                  ])),
            )));
  }

  Widget _buildTextFields() {
    return new Container(
      child: new Column(
        children: <Widget>[
           new TextField(
              controller: _name,
            ),
            new TextField(
              controller: _qrText,
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, "/qrScanner");
              },
              child: Text('Scan'),
            ),
            ElevatedButton(
              onPressed: () {
                nextButton(); //Here I get redirected back to QR Scan page instead of dashboard
              },
              child: Text('Insert'),
              )
        ],
      ),
    );
  }

}

QR扫描页面:

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

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

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

  @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)),
        ],
      ),
    );
  }

  Widget _buildQrView(BuildContext context) {
    return QRView(
      key: qrKey,
      onQRViewCreated: _onQRViewCreated,
    );
  }

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

  passToPreviousPage() {
    controller?.pauseCamera();

    Navigator.pushNamed(context, "/mainPage",
        arguments: QRScan(result!.code));
  }

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

class QRScan {
  final String? result;
  QRScan(this.result);
}
avwztpqn

avwztpqn1#

你可以推送一个路由,使用await来获取结果,然后从推送的页面返回Navigator.of(context).pop()
为此,在推送扫描二维码的路线时使用此码:

onPressed: () async {
  final qrCode = await Navigator.pushNamed(context, "/qrScanner");
},

然后在您扫描二维码的页面中,返回扫描的代码:

Navigator.of(context).pop(result!.code);

您还可以设置路由将返回的类型:

final qrCode = await Navigator.pushNamed<Your_Type_Here>(context, "/qrScanner");

相关问题