import 'dart:convert'; import 'dart:io'; import 'package:chat/data/UserData.dart'; import 'package:chat/data/constants.dart'; import 'package:chat/data/group_data_mgr.dart'; import 'package:chat/generated/i18n.dart'; import 'package:chat/home/qr_scanner_overlay.dart'; import 'package:chat/utils/CustomUI.dart'; import 'package:chat/utils/MessageMgr.dart'; import 'package:chat/utils/app_navigator.dart'; import 'package:flutter/material.dart'; import 'package:flutter_qr_reader/flutter_qr_reader.dart'; import 'package:flutter_qr_reader/qrcode_reader_view.dart'; import 'package:image_picker/image_picker.dart'; import 'package:oktoast/oktoast.dart'; import 'package:url_launcher/url_launcher.dart'; import 'join_group_confirm.dart'; class QrScannerPage extends StatefulWidget { @override _QrScannerPageState createState() => _QrScannerPageState(); } class _QrScannerPageState extends State with SingleTickerProviderStateMixin { String scanImgPath; GlobalKey qrViewKey = GlobalKey(); AnimationController _animationController; Animation _animation; QrReaderViewController qrReaderViewController; @override void initState() { super.initState(); _animationController = new AnimationController( duration: Duration(milliseconds: 600), vsync: this); _animation = Tween(begin: 1.0, end: 0.45).animate(_animationController) ..addListener(() { //这行如果不写,没有动画效果 setState(() {}); }); _animationController.forward(); } bool isScan = false; @override void dispose() { qrReaderViewController = null; super.dispose(); } @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; final double scanWidth = 250; final double borderWidth = 5; final screenRect = Rect.fromLTWH( size.width / 2 - scanWidth / 2 + borderWidth, size.height / 2 - scanWidth / 2 + borderWidth - kBottomNavigationBarHeight, scanWidth - 2 * borderWidth, scanWidth - 2 * borderWidth, ); return Scaffold( appBar: AppBar( leading: IconButton( iconSize: 22, icon: Icon( Icons.arrow_back_ios, color: Colors.white, ), onPressed: () { Navigator.of(context).pop(); }, ), backgroundColor: Colors.black, title: Text(I18n.of(context).scan, textScaleFactor: 1.0, style: TextStyle(color: Colors.white)), centerTitle: true, ), backgroundColor: Colors.black.withOpacity(_animation.value), body: ScanImageView( scanColor: Colors.blueAccent, scanRect: screenRect, child: Stack( alignment: Alignment.center, children: [ scanImgPath == null ? QrReaderView( width: size.width, height: size.height, callback: (container) { qrReaderViewController = container; Future.delayed(Duration(milliseconds: 600), () { qrReaderViewController.startCamera(onQrBack); }); }, ) : SizedBox.expand( child: Image.file( File(scanImgPath), fit: BoxFit.contain, )), Positioned( left: 0, right: 0, bottom: 0, child: Container( color: Colors.black, padding: EdgeInsets.symmetric(vertical: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _iconButton( IconData(0xe658, fontFamily: Constants.IconFontFamily), I18n.of(context).my_qr, () { AppNavigator.pushQrPage(context); }), _iconButton( IconData(0xe626, fontFamily: Constants.IconFontFamily), I18n.of(context).picture, () async { if (await CustomUI.showPhotoPermissionSetting( context)) { _scanImage(); } }) ], ), )) ], )), ); } Future _scanImage() async { stopScan(); print('_scanImage 开始'); var image = await ImagePicker.pickImage(source: ImageSource.gallery); if (image == null) { startScan(); return; } setState(() { scanImgPath = image.path; }); final rest = await FlutterQrReader.imgScan(image); print('_scanImage $rest'); onScan(rest); } void startScan() { isScan = false; qrReaderViewController.startCamera(onQrBack); } void stopScan() { qrReaderViewController.stopCamera(); } onScan(String result) { if (result == null || result.length == 0) { return; } print('扫描 $result'); stopScan(); Navigator.of(context).pop(); if (result.startsWith('https://henho.jphgames.com/')) { result = result.replaceFirst('https://henho.jphgames.com/?', ''); result = utf8.decode(base64Decode(result)); result = 'https://henho.jphgames.com/?' + result; var url = Uri.parse(result); var type = int.parse(url.queryParameters['type']); int expirationTime = int.parse(url.queryParameters['expirationTime']); int curTime = DateTime.now().millisecondsSinceEpoch; print('过期时间$expirationTime'); if (curTime > expirationTime) { showToast(I18n.of(context).qr_outtime); return; } if (type == 1) { var targetId = int.parse(url.queryParameters['sessionId']); //群二维码 print('群二维码'); GroupInfoMgr().getGroupInfo(targetId, isSave: false).then((groupInfo) { print('--------------------'); print(groupInfo); if (groupInfo == null) { showToast(I18n.of(context).no_goupr_info); return; } Navigator.push(Constants.getCurrentContext(), MaterialPageRoute(builder: (BuildContext context) { return JoinGroupConfirmPage( groupInfoModel: groupInfo, ); })); }); } else { //个人二维码 print('个人二维码'); var targetId = int.parse(url.queryParameters['sessionId']); if (targetId == UserData().basicInfo.userId) { //我的页面 MessageMgr().emit('Show My Profile'); } else { AppNavigator.pushProfileInfoPage(context, targetId, addMode: 1); } } } else { //其他的条码 launch(result); } } onQrBack(String result, List points) { print('扫描结果 $result'); if (isScan == true) return; isScan = true; stopScan(); onScan(result); } Widget _iconButton(IconData code, String iconName, Function onTap) { return InkWell( onTap: onTap, child: Container( child: Column(children: [ Icon( code, size: 30, color: Colors.white, ), SizedBox(height: 5), Text( iconName, textScaleFactor: 1.0, style: TextStyle(color: Colors.white), ) ]))); } }