【发布时间】:2021-06-06 15:04:17
【问题描述】:
我正在构建一个扫描二维码的 2FA 应用程序。然后它解析 QR 码中的 uri 并返回一个 totp 码。但是,我在使用 Navigator.of(context).pop() 关闭 CupertinoActionSheet 时遇到问题。
我希望它像这样工作:
- 当用户点击“添加”按钮时,会显示操作表。
- 当用户点击“扫描二维码”时,操作表必须关闭,然后继续扫描。
当我有以下代码时,出现以下错误:“查找已停用小部件的祖先是不安全的。 此时小部件的元素树的状态不再稳定。 要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。"
代码:
home_screen.dart
import 'dart:io';
import 'package:duckie/blocs/manual_input/manual_input_bloc.dart';
import 'package:duckie/blocs/qr_code_scanner/qr_code_scanner_bloc.dart';
import 'package:duckie/screens/manual_input/manual_input_screen.dart';
import 'package:duckie/screens/widgets/alert_dialog.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:duckie/shared/text_styles.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'title',
style: TextStyles.appBarText,
).tr(),
centerTitle: false,
elevation: 0.0,
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () {
if (Platform.isAndroid) {
showAndroidModalBottomSheet(context);
} else if (Platform.isIOS) {
showIosActionSheet(context);
}
},
),
],
),
body: BlocConsumer<QrCodeScannerBloc, QrCodeScannerState>(
listener: (context, state) {
if (state is QrCodeScannerError) {
Platform.isAndroid
? CustomAlertDialog.showAndroidAlertDialog(context,
state.alertDialogErrorTitle, state.alertDialogErrorContent)
: CustomAlertDialog.showIosAlertDialog(context,
state.alertDialogErrorTitle, state.alertDialogErrorContent);
}
},
builder: (context, state) {
if (state is QrCodeScannerFinal) {
return Column(
children: [
Text(state.accountName),
Text(state.issuer),
Text(state.otp),
],
);
}
return Container();
},
),
);
}
}
void showAndroidModalBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return ListView(
shrinkWrap: true,
children: [
ListTile(
onTap: () {},
leading: Icon(Icons.qr_code),
title: Text('scan-qr-code').tr(),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed('/manual-input');
},
leading: Icon(Icons.keyboard),
title: Text('manual-input').tr(),
),
ListTile(
onTap: () {
Navigator.of(context).pop();
},
leading: Icon(Icons.cancel),
title: Text('cancel').tr(),
)
],
);
},
);
}
void showIosActionSheet(BuildContext context) {
showCupertinoModalPopup(
context: context,
builder: (BuildContext context) {
return CupertinoActionSheet(
title: Text('action-sheet-title').tr(),
message: Text('action-sheet-message').tr(),
actions: [
CupertinoActionSheetAction(
onPressed: () async {
Navigator.pop(context);
final String qrCodeResponse =
await FlutterBarcodeScanner.scanBarcode(
'#FF6666', 'cancel'.tr(), true, ScanMode.QR);
BlocProvider.of<QrCodeScannerBloc>(context).add(
GetQrCodeResponseEvent(qrCodeResponse),
);
// final String uri =
// 'otpauth://totp/Karol%27s%20Nextcloud%3Aszakes1%40drive.karolzientek.tech?secret=KVZKSQ74SSAVCR27&issuer=Karol%27s%20Nextcloud';
},
child: Text('scan-qr-code').tr(),
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pushNamed('/manual-input');
},
child: Text('manual-input').tr(),
),
CupertinoActionSheetAction(
isDestructiveAction: true,
onPressed: () {
Navigator.of(context).pop();
},
child: Text('cancel').tr(),
)
],
);
},
);
}
【问题讨论】: