项目图片我正在使用 webviewx 在我的颤振项目中显示一个 Web 应用程序。扫描结果输入字段最初是可编辑的。但是,如果我扫描,在输入字段中设置值并再次导航回此页面,则输入字段不再收听。键盘无法打开,我无法编辑输入字段。
网页浏览
class AppWebView extends StatelessWidget {
AppWebView({Key? key}) : super(key: key);
final AppController _ctrl = Get.put<AppController>(AppController());
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: WebViewX(
key: const ValueKey(ksWebViewKey),
javascriptMode: JavascriptMode.unrestricted,
initialContent: ksURL,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
onWebViewCreated: (controller) async {
_ctrl.webviewController = controller;
//await _ctrl.writeJson();
},
onPageFinished: (value) async {
await _ctrl.setIPandUI();
},
dartCallBacks: {
DartCallback(
name: ksScanCallBack,
callBack: (msg) {
log('scan');
Get.to(
() => BarcodeScanner(
appController: Get.put<AppController>(AppController()),
iawvctrl: Get.put<AppController>(AppController()).webviewController,
),
);
},
),
DartCallback(
name: ksTakeImageCallBack,
callBack: (msg) async {
Get.to(() => TakeImage());
log('take image');
},
),
DartCallback(
name: ksUpdateIPCallBack,
callBack: (msg) async {
log('update ip');
_ctrl.updateIP();
},
)
},
),
),
);
}
}
扫描器
import 'dart:developer';
import 'dart:io';
import 'package:weview/utils/export.util.dart';
class BarcodeScanner extends StatefulWidget {
const BarcodeScanner({
Key? key,
required this.appController,
required this.iawvctrl,
}) : super(key: key);
final AppController appController;
final WebViewXController iawvctrl;
@override
State<StatefulWidget> createState() => _BarcodeScannerState();
}
class _BarcodeScannerState extends State<BarcodeScanner> {
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) async {
setState(() {
result = scanData;
});
widget.appController.barcodeResult.value = scanData.code.toString();
controller.pauseCamera();
log(scanData.code.toString());
String multilineRes = scanData.code.toString();
String res = '';
for (var i = 0; i < multilineRes.length - 1; i++) {
if (multilineRes[i] != '\n') {
res += multilineRes[i];
} else {
break;
}
}
Get.back();
await widget.iawvctrl
.evalRawJavascript('window.setScanData("$res")', inGlobalContext: false)
.then((value) => log(value.toString()));
return;
},
);
}
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();
}
}