|
|
import 'dart:io';
|
|
|
|
|
|
import 'package:camera/camera.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_drag_scale/core/drag_scale_widget.dart';
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
|
import 'package:hyzp_ybqx511528_xingwen/components/customDialogFaceReg.dart';
|
|
|
import 'package:hyzp_ybqx511528_xingwen/components/dioFun.dart';
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
|
|
import '../../components/commonFun.dart';
|
|
|
import '../../services/EventBus.dart';
|
|
|
|
|
|
class FaceReg extends StatefulWidget {
|
|
|
FaceReg({this.arguments, Key key}) : super(key: key);
|
|
|
var arguments;
|
|
|
|
|
|
_LoginPageState createState() => _LoginPageState();
|
|
|
}
|
|
|
|
|
|
class _LoginPageState extends State<FaceReg> {
|
|
|
//try_setState(); //避免异常报错
|
|
|
try_setState() {
|
|
|
try {
|
|
|
setState(() {});
|
|
|
} catch (e) {
|
|
|
print('setState(() {})异常:${e}');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Future<void> camerasInit() async {
|
|
|
try {
|
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
cameras = await availableCameras();
|
|
|
print(cameras.toString());
|
|
|
} on CameraException catch (e) {
|
|
|
//logError(e.code, e.description);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
String imagePath = '';
|
|
|
Size imageSize;
|
|
|
String _username;
|
|
|
//人脸注册页面,这里建议自动填入当前登录用户名
|
|
|
TextEditingController _controller = TextEditingController(text: g_userInfo.username);
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
camerasInit();
|
|
|
|
|
|
//监听人脸注册数据更新事件
|
|
|
eventBus.on<FaceRegUpdateEvent>().listen((event) async {
|
|
|
print(event.str);
|
|
|
try_setState();
|
|
|
});
|
|
|
|
|
|
super.initState();
|
|
|
}
|
|
|
|
|
|
//监听登录页面销毁的事件
|
|
|
dispose() {
|
|
|
super.dispose();
|
|
|
eventBus.fire(new UserEvent('登录成功...'));
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
return Scaffold(
|
|
|
appBar: PreferredSize(
|
|
|
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
|
|
|
// 设置appBar高度
|
|
|
child: AppBar(
|
|
|
automaticallyImplyLeading: false,
|
|
|
centerTitle: true,
|
|
|
titleSpacing: 0.0,
|
|
|
//设置title的左边距
|
|
|
flexibleSpace: Container(
|
|
|
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
|
|
|
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
|
|
|
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
|
|
|
child: Container(
|
|
|
//height: ScreenUtil().setHeight(173),
|
|
|
decoration: BoxDecoration(
|
|
|
gradient: LinearGradient(
|
|
|
begin: Alignment.centerLeft,
|
|
|
end: Alignment.centerRight,
|
|
|
colors: [
|
|
|
Color.fromRGBO(12, 186, 156, 1),
|
|
|
Color.fromRGBO(39, 127, 235, 1),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
// decoration: BoxDecoration(
|
|
|
// gradient: LinearGradient(colors: [
|
|
|
// Color(0xFF0018EB),
|
|
|
// Color(0xFF01C1D9),
|
|
|
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
|
|
|
// ),
|
|
|
),
|
|
|
),
|
|
|
title: Padding(
|
|
|
padding: EdgeInsets.only(left: 0, right: 0),
|
|
|
child: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
children: [
|
|
|
getIconAndTextButton(
|
|
|
iconColor: Colors.white,
|
|
|
iconData: Icons.chevron_left_outlined,
|
|
|
onPress: () {
|
|
|
Navigator.pop(context);
|
|
|
},
|
|
|
),
|
|
|
Expanded(
|
|
|
child: Text("人脸注册",
|
|
|
style: TextStyle(color: Colors.white, fontSize: 20),
|
|
|
textAlign: TextAlign.center,
|
|
|
overflow: TextOverflow.ellipsis),
|
|
|
),
|
|
|
SizedBox(width: 50),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
body: Container(
|
|
|
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
|
|
|
child: ListView(
|
|
|
children: <Widget>[
|
|
|
//解决 Flutter ListView 子元素 无限宽度 的问题
|
|
|
Container(
|
|
|
alignment: Alignment.topCenter,
|
|
|
child: Column(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
children: <Widget>[
|
|
|
Center(
|
|
|
child: Container(
|
|
|
margin: EdgeInsets.only(top: 20, bottom: 5, left: 0, right: 0),
|
|
|
height: ScreenUtil().setHeight(200),
|
|
|
width: ScreenUtil().setWidth(260),
|
|
|
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
|
|
|
),
|
|
|
),
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
children: [
|
|
|
SizedBox(width: 10),
|
|
|
Container(
|
|
|
padding: EdgeInsets.only(top: 16),
|
|
|
child: Text('用户名: ', style: TextStyle(fontSize: 18)),
|
|
|
),
|
|
|
Container(
|
|
|
height: ScreenUtil().setHeight(160),
|
|
|
width: ScreenUtil().setWidth(500),
|
|
|
child: TextField(
|
|
|
//textAlign: TextAlign.right,
|
|
|
textAlignVertical: TextAlignVertical.center,
|
|
|
maxLines: 1,
|
|
|
style: TextStyle(fontSize: 18),
|
|
|
decoration: InputDecoration(
|
|
|
hintText: '請輸入用户名',
|
|
|
//border: InputBorder.none, //TextField去掉下划线
|
|
|
contentPadding: EdgeInsets.only(right: 0),
|
|
|
enabledBorder: new UnderlineInputBorder(
|
|
|
borderSide: BorderSide(color: Colors.blue)),
|
|
|
focusedBorder: new UnderlineInputBorder(
|
|
|
borderSide: BorderSide(color: Colors.blue)),
|
|
|
),
|
|
|
controller: _controller,
|
|
|
//利用控制器初始化文本
|
|
|
onChanged: (value) {
|
|
|
_username = value;
|
|
|
},
|
|
|
),
|
|
|
),
|
|
|
SizedBox(width: 10),
|
|
|
Container(
|
|
|
width: ScreenUtil().setWidth(220),
|
|
|
padding: EdgeInsets.only(top: 16),
|
|
|
child: FlatButton(
|
|
|
color: Colors.black12,
|
|
|
child: Text('本人', style: TextStyle(color: Colors.blue, fontSize: 18)),
|
|
|
onPressed: () {
|
|
|
_controller.text = g_userInfo.username;
|
|
|
},
|
|
|
),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
//SizedBox(height: 30),
|
|
|
SizedBox(height: 10),
|
|
|
//480*720
|
|
|
Text(null == imageSize ? '' : '宽高:${imageSize.width}x${imageSize.height}',
|
|
|
style: TextStyle(fontSize: 18)),
|
|
|
SizedBox(height: 5),
|
|
|
Container(
|
|
|
alignment: Alignment(0, 0),
|
|
|
width: ScreenUtil().setWidth(980),
|
|
|
height: ScreenUtil().setHeight(760),
|
|
|
decoration: BoxDecoration(
|
|
|
border: Border.all(color: Colors.orange, width: 1.0),
|
|
|
borderRadius: BorderRadius.circular(5),
|
|
|
),
|
|
|
child: _getImage(imagePath),
|
|
|
),
|
|
|
SizedBox(height: 25),
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
|
children: [
|
|
|
getBtnSizeX(
|
|
|
width: 90,
|
|
|
text: "拍照",
|
|
|
onPressedFun: () {
|
|
|
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
|
|
|
_username = _controller.text;
|
|
|
Navigator.pushNamed(context, '/faceReg_take_pictuer',
|
|
|
arguments: 'FaceReg')
|
|
|
.then((_imagePath) {
|
|
|
_controller.text = _username;
|
|
|
imagePath = _imagePath as String;
|
|
|
if (imagePath.isNotEmpty) {
|
|
|
print('imagePath = $imagePath');
|
|
|
//imageSize = Size(480, 720);
|
|
|
getImageSize(imagePath);
|
|
|
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新'));
|
|
|
}
|
|
|
});
|
|
|
}),
|
|
|
getBtnSizeX(
|
|
|
width: 90,
|
|
|
text: "选择图片",
|
|
|
onPressedFun: () {
|
|
|
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
|
|
|
_getImageGallery();
|
|
|
}),
|
|
|
getBtnSizeX(
|
|
|
width: 90,
|
|
|
text: "人脸注册",
|
|
|
onPressedFun: (_controller.text.isEmpty && imagePath.isEmpty)
|
|
|
? null
|
|
|
: () {
|
|
|
//人脸注册,username 用户名,filePath 人脸图片路径
|
|
|
if (_controller.text.isNotEmpty && imagePath.isNotEmpty) {
|
|
|
print('等待人脸注册或更新确认');
|
|
|
Navigator.of(context)
|
|
|
.push(
|
|
|
PageRouteBuilder(
|
|
|
opaque: false,
|
|
|
pageBuilder: (context, animation, secondaryAnimation) =>
|
|
|
CustomDialogFaceReg(
|
|
|
title: '人脸注册或更新确认',
|
|
|
username: _username,
|
|
|
imagePath: imagePath,
|
|
|
imageSize: imageSize,
|
|
|
),
|
|
|
),
|
|
|
)
|
|
|
.then((ret) async {
|
|
|
print('value = $ret');
|
|
|
if (ret) {
|
|
|
print('用户已确认,开始处理人脸注册或更新!');
|
|
|
faceRegFun(
|
|
|
username: _username,
|
|
|
filePath: imagePath,
|
|
|
context: context);
|
|
|
} else {
|
|
|
print('用户取消了人脸注册或更新');
|
|
|
}
|
|
|
});
|
|
|
} else if (_controller.text.isEmpty) {
|
|
|
Fluttertoast.showToast(
|
|
|
msg: "用户名不能为空!",
|
|
|
toastLength: Toast.LENGTH_SHORT,
|
|
|
gravity: ToastGravity.CENTER,
|
|
|
);
|
|
|
} else if (imagePath.isEmpty) {
|
|
|
Fluttertoast.showToast(
|
|
|
msg: "请选择用户人脸图片!",
|
|
|
toastLength: Toast.LENGTH_SHORT,
|
|
|
gravity: ToastGravity.CENTER,
|
|
|
);
|
|
|
}
|
|
|
}),
|
|
|
],
|
|
|
),
|
|
|
// RaisedButton(
|
|
|
// child: Text('人脸登录'),
|
|
|
// onPressed: () {
|
|
|
// Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
|
|
|
// }),
|
|
|
SizedBox(height: 10),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
],
|
|
|
)),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
//从相册选取图片
|
|
|
Future _getImageGallery() async {
|
|
|
final imagePicker = ImagePicker();
|
|
|
_username = _controller.text;
|
|
|
//final pickedFile = await imagePicker.getImage(source: ImageSource.gallery, maxWidth: 400);
|
|
|
imagePicker.getImage(source: ImageSource.gallery, maxWidth: 480).then((pickedFile) {
|
|
|
if (pickedFile != null) {
|
|
|
print('pickedFile = ${pickedFile.path}');
|
|
|
imagePath = pickedFile.path;
|
|
|
getImageSize(imagePath);
|
|
|
} else {
|
|
|
print('No image selected.');
|
|
|
}
|
|
|
_controller.text = _username;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
//定义一个组件显示图片
|
|
|
_getImage(String filePath) {
|
|
|
print('filePath = $filePath');
|
|
|
if (null == imageSize || filePath.isEmpty) {
|
|
|
return Text("注意:\n1、请输入“已注册”的用户名;\n2、请选择包含“用户人脸”的图片;\n3、两样都选好后再进行注册,不然可能失败!");
|
|
|
}
|
|
|
|
|
|
double _width = ScreenUtil().setWidth(980);
|
|
|
double _heigth = _width * (imageSize.height / imageSize.width);
|
|
|
|
|
|
final _image = Image.file(File(filePath));
|
|
|
|
|
|
// 预先获取图片信息
|
|
|
return SingleChildScrollView(
|
|
|
//滑动的方向 Axis.vertical为垂直方向滑动,Axis.horizontal 为水平方向
|
|
|
scrollDirection: Axis.vertical,
|
|
|
//true 滑动到底部
|
|
|
reverse: false,
|
|
|
padding: EdgeInsets.all(0.0),
|
|
|
//滑动到底部回弹效果
|
|
|
physics: BouncingScrollPhysics(),
|
|
|
child: Column(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
children: <Widget>[
|
|
|
Container(
|
|
|
width: _width,
|
|
|
height: _heigth,
|
|
|
// child: PinchZoomImage( //不好用
|
|
|
// //image: Image.network('https://i.imgur.com/tKg0XEb.jpg'),
|
|
|
// image: _image,
|
|
|
// zoomedBackgroundColor: Color.fromRGBO(240, 240, 240, 1.0),
|
|
|
// hideStatusBarWhileZooming: true,
|
|
|
// onZoomStart: () {
|
|
|
// print('Zoom started');
|
|
|
// },
|
|
|
// onZoomEnd: () {
|
|
|
// print('Zoom finished');
|
|
|
// },
|
|
|
// ),
|
|
|
|
|
|
//DragScaleContainer 插件只能放大,不能缩小到比原始尺寸小
|
|
|
child: DragScaleContainer(doubleTapStillScale: true, child: _image
|
|
|
// child: Image(
|
|
|
// image: NetworkImage(
|
|
|
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
|
|
|
// ),
|
|
|
),
|
|
|
//child: _image,
|
|
|
//一个大坑:用 AssetImage(filePath) 方式,首次加载拍照返回的照片,始终报错,刷新后则能够正常加载。
|
|
|
// 用 Container 的 child 方式解决
|
|
|
// decoration: BoxDecoration(
|
|
|
// image: DecorationImage(image: AssetImage(filePath), fit: BoxFit.cover),
|
|
|
// ),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// 预先获取图片信息
|
|
|
Future getImageSize(String filePath) async {
|
|
|
Image image = Image.file(File.fromUri(Uri.parse(filePath)));
|
|
|
image.image
|
|
|
.resolve(new ImageConfiguration())
|
|
|
.addListener(new ImageStreamListener((ImageInfo info, bool _) {
|
|
|
imageSize = Size(
|
|
|
info.image.width.toDouble(),
|
|
|
info.image.height.toDouble(),
|
|
|
);
|
|
|
print('imageSize = $imageSize');
|
|
|
//必须延迟刷新,否则启动App后,第一次进行拍照返回会抛异常,无法显示返回的照片
|
|
|
//启动App后,第一次进行拍照返回,在 AS Terminal 按 R 刷新可以显示图片。
|
|
|
//暂存,后续解决
|
|
|
try_setState();
|
|
|
// Future.delayed(const Duration(milliseconds: 3000), () {
|
|
|
// //try_setState();
|
|
|
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新')); //这样刷新有效
|
|
|
// });
|
|
|
}));
|
|
|
}
|
|
|
}
|