import 'dart:io'; import 'package:chat/generated/i18n.dart'; import 'package:chat/utils/CustomUI.dart'; import 'package:chat/utils/LoadingDialog.dart'; import 'package:chat/utils/MessageMgr.dart'; import 'package:chat/utils/screen.dart'; import 'package:extended_image/extended_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:image_cropper/image_cropper.dart'; import 'package:image_picker/image_picker.dart'; import '../utils/HttpUtil.dart'; import 'package:dio/dio.dart'; import "../data/UserData.dart"; import '../utils/TokenMgr.dart'; class MyHeadViewPage extends StatefulWidget { MyHeadViewPage({Key key}) : super(key: key); @override _MyHeadViewPageState createState() => new _MyHeadViewPageState(); } class _MyHeadViewPageState extends State with SingleTickerProviderStateMixin { AnimationController _animationController; Animation _animation; Function animationListener; List doubleTapScales = [1.0, 2.0]; @override void initState() { super.initState(); _animationController = AnimationController( duration: const Duration(milliseconds: 150), vsync: this); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea(child: _buildBody()), backgroundColor: Colors.black, ); } Widget _buildHeadView() { return ExtendedImageGesturePageView( children: [ InkWell( onTap: () { Navigator.pop(context); }, child: ExtendedImage.network( UserData().basicInfo.headimgurl, fit: BoxFit.contain, mode: ExtendedImageMode.gesture, initGestureConfigHandler: (state) { return GestureConfig( inPageView: true, maxScale: 5, initialAlignment: InitialAlignment.topCenter, animationMaxScale: 5, cacheGesture: false); }, onDoubleTap: (ExtendedImageGestureState state) { var pointerDownPosition = state.pointerDownPosition; double begin = state.gestureDetails.totalScale; double end; //remove old _animation?.removeListener(animationListener); //stop pre _animationController.stop(); //reset to use _animationController.reset(); if (begin == doubleTapScales[0]) { end = doubleTapScales[1]; } else { end = doubleTapScales[0]; } animationListener = () { //print(_animation.value); state.handleDoubleTap( scale: _animation.value, doubleTapPosition: pointerDownPosition); }; _animation = _animationController .drive(Tween(begin: begin, end: end)); _animation.addListener(animationListener); _animationController.forward(); }, )) ], ); } Widget _buildBody() { return Stack( children: [ _buildHeadView(), Positioned( child: _buildChangeButton(), bottom: 40, ) ], ); } Widget _buildChangeButton() { return InkWell( onTap: _sendPicture, child: Container( alignment: Alignment.center, width: Screen.width, child: Container( height: 47.5, alignment: Alignment.center, width: 230, child: Text( I18n.of(context).upload_avatar, style: TextStyle(color: Colors.white, fontSize: 17.5), ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(24), color: Color(0xFF181818)), ))); } void _sendPicture() async { if (await CustomUI.showPhotoPermissionSetting(context)) { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return LoadingDialog( text: "", ); }); var tempFile = await ImagePicker.pickImage(source: ImageSource.gallery); Navigator.of(context).pop(); if (tempFile != null) { _cropPicture(tempFile); } } } void _cropPicture(tempFile) async { File croppedFile = await ImageCropper.cropImage( sourcePath: tempFile.path, aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1), ); if (croppedFile != null) { Map data = {"type": 1, "userId": UserData().basicInfo.userId}; data['sign'] = TokenMgr().getSign(data); Response res = await HttpUtil() .uploadFile(croppedFile, data, 'upload/file/postflie', 'image'); var resData = res.data; if (resData['code'] == 0) { UserData().basicInfo.headimgurl = resData['msg']; MessageMgr().emit('change_my_headview'); if (mounted) { setState(() {}); } } } } @override void dispose() { super.dispose(); } }