Commit 51f55f908e97f4080a35b069c968011f030f9d00

Authored by wdn127929
1 parent 357ee93d

相册、相机选择图片

@@ -2,15 +2,23 @@ import 'dart:io'; @@ -2,15 +2,23 @@ import 'dart:io';
2 2
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 import 'package:flutter_screenutil/flutter_screenutil.dart';
5 -import 'package:image_picker/image_picker.dart'; 5 +import 'package:one_key/pages/online_check/photo_view_wiget.dart';
  6 +
6 import 'package:one_key/provider/online_check_edit_provider.dart'; 7 import 'package:one_key/provider/online_check_edit_provider.dart';
7 import 'package:one_key/res/colors.dart'; 8 import 'package:one_key/res/colors.dart';
8 import 'package:one_key/utils/utils.dart'; 9 import 'package:one_key/utils/utils.dart';
  10 +import 'package:one_key/widgets/MyDivider.dart';
  11 +import 'package:one_key/widgets/v_empty_view.dart';
9 import 'package:provider/provider.dart'; 12 import 'package:provider/provider.dart';
10 13
  14 +import 'package:image_picker/image_picker.dart';
  15 +import 'package:video_player/video_player.dart';
  16 +
11 final int MAX_IMAGE_NUMBER = 9; 17 final int MAX_IMAGE_NUMBER = 9;
  18 +typedef void OnPickImageCallback(
  19 + double maxWidth, double maxHeight, int quality);
12 20
13 -class ImgPickerWidget extends StatelessWidget { 21 +class ImgPickerWidget extends StatefulWidget {
14 final ScrollController scrollController; 22 final ScrollController scrollController;
15 final Color borderColor; 23 final Color borderColor;
16 final ValueChanged onChange; 24 final ValueChanged onChange;
@@ -21,46 +29,121 @@ class ImgPickerWidget extends StatelessWidget { @@ -21,46 +29,121 @@ class ImgPickerWidget extends StatelessWidget {
21 this.onChange}) 29 this.onChange})
22 : super(key: key); 30 : super(key: key);
23 31
  32 + @override
  33 + _ImgPickerWidgetState createState() => _ImgPickerWidgetState();
  34 +}
  35 +
  36 +class _ImgPickerWidgetState extends State<ImgPickerWidget> {
  37 + File _image;
  38 + final picker = ImagePicker();
  39 + OnlineCheckEditProvider _onlineCheckEditProvider;
  40 +
24 //相册 相机 41 //相册 相机
25 - Future _getFromPictureOrCamera(context, imageSource) async {  
26 - // File image = await ImagePicker.pickImage(  
27 - // source: imageSource,  
28 - // );  
29 - // if (image != null) {  
30 - // _provider.imageList.add(image);  
31 - // _provider.notifyListeners();  
32 - // }  
33 - // _provider.uploadTravelReleaseImg(image); 42 + // Future _getFromPictureOrCamera(context, imageSource) async {
  43 + // File image = await picker.getImage(
  44 + // source: imageSource,
  45 + // );
  46 + // if (image != null) {
  47 + // _provider.imageList.add(image);
  48 + // _provider.notifyListeners();
  49 + // }
  50 + // // _provider.uploadTravelReleaseImg(image);
  51 + // }
  52 +
  53 + Future _getFromPictureOrCamera(imageSource) async {
  54 + final pickedFile = await picker.getImage(source: imageSource);
  55 +
  56 + setState(() {
  57 + if (pickedFile != null) {
  58 + _image = File(pickedFile.path);
  59 + _onlineCheckEditProvider.imageList.add(_image);
  60 + _onlineCheckEditProvider.notifyListeners();
  61 + } else {
  62 + print('No image selected.');
  63 + }
  64 + });
  65 + }
  66 +
  67 + @override
  68 + void dispose() {
  69 + super.dispose();
34 } 70 }
35 71
36 Future _openModalBottomSheet(context) async { 72 Future _openModalBottomSheet(context) async {
37 final option = await showModalBottomSheet( 73 final option = await showModalBottomSheet(
38 context: context, 74 context: context,
  75 + backgroundColor: Colors.transparent,
39 builder: (BuildContext context) { 76 builder: (BuildContext context) {
40 return Container( 77 return Container(
41 - height: 200.0, 78 + // height: ScreenUtil().setWidth(180 * 2),
  79 + decoration: BoxDecoration(
  80 + color: MyColours.color_ffffff,
  81 + borderRadius: BorderRadius.only(
  82 + topLeft: Radius.circular(ScreenUtil().setWidth(24)),
  83 + topRight: Radius.circular(ScreenUtil().setWidth(24)))),
42 child: Column( 84 child: Column(
  85 + mainAxisSize: MainAxisSize.min,
43 children: <Widget>[ 86 children: <Widget>[
44 - ListTile(  
45 - title: Text('拍照', textAlign: TextAlign.center), 87 + InkWell(
46 onTap: () { 88 onTap: () {
47 - _getFromPictureOrCamera(context, ImageSource.camera); 89 + _getFromPictureOrCamera(ImageSource.camera);
48 Navigator.pop(context); 90 Navigator.pop(context);
49 }, 91 },
  92 + child: Padding(
  93 + padding: EdgeInsets.symmetric(
  94 + vertical: ScreenUtil().setWidth(18 * 2)),
  95 + child: Text(
  96 + '拍摄',
  97 + style: TextStyle(
  98 + fontSize: ScreenUtil().setSp(32),
  99 + color: MyColours.color_353535,
  100 + fontWeight: FontWeight.bold),
  101 + ),
  102 + ),
  103 + ),
  104 + MyDivider(
  105 + double.infinity,
  106 + ScreenUtil().setWidth(2),
  107 + color: MyColours.color_EEEEEE,
50 ), 108 ),
51 - ListTile(  
52 - title: Text('从相册选择', textAlign: TextAlign.center), 109 + InkWell(
53 onTap: () { 110 onTap: () {
54 - _getFromPictureOrCamera(context, ImageSource.gallery); 111 + _getFromPictureOrCamera(ImageSource.gallery);
55 Navigator.pop(context); 112 Navigator.pop(context);
56 }, 113 },
  114 + child: Padding(
  115 + padding: EdgeInsets.symmetric(
  116 + vertical: ScreenUtil().setWidth(18 * 2)),
  117 + child: Text(
  118 + '从相册选择',
  119 + style: TextStyle(
  120 + fontSize: ScreenUtil().setSp(32),
  121 + color: MyColours.color_353535,
  122 + fontWeight: FontWeight.bold),
  123 + ),
  124 + ),
57 ), 125 ),
58 - ListTile(  
59 - title: Text('取消', textAlign: TextAlign.center), 126 + MyDivider(
  127 + double.infinity,
  128 + ScreenUtil().setWidth(10),
  129 + color: MyColours.color_EEEEEE,
  130 + ),
  131 + InkWell(
60 onTap: () { 132 onTap: () {
61 Navigator.pop(context, '取消'); 133 Navigator.pop(context, '取消');
62 }, 134 },
63 - ), 135 + child: Padding(
  136 + padding: EdgeInsets.symmetric(
  137 + vertical: ScreenUtil().setWidth(18 * 2)),
  138 + child: Text(
  139 + '取消',
  140 + style: TextStyle(
  141 + fontSize: ScreenUtil().setSp(32),
  142 + color: MyColours.color_353535,
  143 + fontWeight: FontWeight.bold),
  144 + ),
  145 + ),
  146 + )
64 ], 147 ],
65 ), 148 ),
66 ); 149 );
@@ -71,7 +154,7 @@ class ImgPickerWidget extends StatelessWidget { @@ -71,7 +154,7 @@ class ImgPickerWidget extends StatelessWidget {
71 OnlineCheckEditProvider _provider = 154 OnlineCheckEditProvider _provider =
72 Provider.of<OnlineCheckEditProvider>(context, listen: false); 155 Provider.of<OnlineCheckEditProvider>(context, listen: false);
73 return GridView.builder( 156 return GridView.builder(
74 - controller: scrollController, 157 + controller: widget.scrollController,
75 // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)), 158 // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
76 shrinkWrap: true, 159 shrinkWrap: true,
77 itemCount: count, 160 itemCount: count,
@@ -100,16 +183,24 @@ class ImgPickerWidget extends StatelessWidget { @@ -100,16 +183,24 @@ class ImgPickerWidget extends StatelessWidget {
100 width: ScreenUtil().setWidth(90 * 2), 183 width: ScreenUtil().setWidth(90 * 2),
101 height: ScreenUtil().setWidth(90 * 2), 184 height: ScreenUtil().setWidth(90 * 2),
102 decoration: BoxDecoration( 185 decoration: BoxDecoration(
103 - border: Border.all(  
104 - color: MyColours.color_E0E0E0,  
105 - width: ScreenUtil().setWidth(2)),  
106 - color: Theme.of(context).backgroundColor), 186 + border: Border.all(
  187 + color: MyColours.color_E0E0E0,
  188 + width: ScreenUtil().setWidth(2)),
  189 + ),
107 child: Column( 190 child: Column(
108 children: [ 191 children: [
  192 + VEmptyView(74),
109 Image.asset( 193 Image.asset(
110 Utils.getImgPath('add_image'), 194 Utils.getImgPath('add_image'),
111 width: ScreenUtil().setWidth(32), 195 width: ScreenUtil().setWidth(32),
112 height: ScreenUtil().setWidth(32), 196 height: ScreenUtil().setWidth(32),
  197 + ),
  198 + VEmptyView(10),
  199 + Text(
  200 + '添加照片',
  201 + style: TextStyle(
  202 + fontSize: ScreenUtil().setSp(24),
  203 + color: MyColours.color_999999),
113 ) 204 )
114 ], 205 ],
115 )), 206 )),
@@ -117,13 +208,51 @@ class ImgPickerWidget extends StatelessWidget { @@ -117,13 +208,51 @@ class ImgPickerWidget extends StatelessWidget {
117 } 208 }
118 return _provider.imageList.length < 1 209 return _provider.imageList.length < 1
119 ? Text('') 210 ? Text('')
120 - : Image.file(_provider.imageList[index], fit: BoxFit.cover); 211 + : InkWell(
  212 + onTap: () {
  213 + _showPhotoView(context, index, _provider.imageList[index]);
  214 + },
  215 + child:
  216 + Image.file(_provider.imageList[index], fit: BoxFit.cover),
  217 + );
121 }); 218 });
122 } 219 }
123 220
  221 + //查看大图
  222 + _showPhotoView(BuildContext context, int index, List imgs,
  223 + {isShow = false, List dashName}) async {
  224 + // if (imgs.length == 1 &&
  225 + // imgs[0] ==
  226 + // 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {
  227 + // imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';
  228 + // }
  229 + Utils.setBarStatus(false, color: Colors.black);
  230 + dynamic result = await showGeneralDialog(
  231 + context: context,
  232 + barrierDismissible: false,
  233 + // barrierColor: Colors.red,
  234 + barrierLabel:
  235 + MaterialLocalizations.of(context).modalBarrierDismissLabel,
  236 + transitionDuration: const Duration(milliseconds: 150),
  237 + pageBuilder: (BuildContext context, Animation animation,
  238 + Animation secondaryAnimation) {
  239 + Widget child = Stack(
  240 + children: <Widget>[
  241 + PhotoPreview(
  242 + initialIndex: index,
  243 + photoList: imgs,
  244 + isShow: isShow,
  245 + dashName: dashName)
  246 + ],
  247 + );
  248 + return child;
  249 + });
  250 + Utils.setBarStatus(true, color: Colors.white);
  251 + }
  252 +
124 @override 253 @override
125 Widget build(BuildContext context) { 254 Widget build(BuildContext context) {
126 - OnlineCheckEditProvider _provider = 255 + _onlineCheckEditProvider =
127 Provider.of<OnlineCheckEditProvider>(context, listen: true); 256 Provider.of<OnlineCheckEditProvider>(context, listen: true);
128 return Container( 257 return Container(
129 width: double.infinity, 258 width: double.infinity,
@@ -158,11 +287,13 @@ class ImgPickerWidget extends StatelessWidget { @@ -158,11 +287,13 @@ class ImgPickerWidget extends StatelessWidget {
158 Padding( 287 Padding(
159 padding: EdgeInsets.all(ScreenUtil().setWidth(40)), 288 padding: EdgeInsets.all(ScreenUtil().setWidth(40)),
160 child: _getGridImg( 289 child: _getGridImg(
161 - _provider.imageList.length < MAX_IMAGE_NUMBER  
162 - ? _provider.imageList.length + 1  
163 - : _provider.imageList.length, 290 + _onlineCheckEditProvider.imageList.length < MAX_IMAGE_NUMBER
  291 + ? _onlineCheckEditProvider.imageList.length + 1
  292 + : _onlineCheckEditProvider.imageList.length,
164 context, 293 context,
165 - _provider.imageList.length == MAX_IMAGE_NUMBER ? true : false), 294 + _onlineCheckEditProvider.imageList.length == MAX_IMAGE_NUMBER
  295 + ? true
  296 + : false),
166 ) 297 )
167 // _getGridImg(1, context) 298 // _getGridImg(1, context)
168 ], 299 ],
  1 +import 'dart:math';
  2 +
  3 +import 'package:flutter/cupertino.dart';
  4 +import 'package:flutter/material.dart';
  5 +import 'package:cached_network_image/cached_network_image.dart';
  6 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  7 +import 'package:one_key/res/colors.dart';
  8 +import 'package:photo_view/photo_view.dart';
  9 +import 'package:photo_view/photo_view_gallery.dart';
  10 +
  11 +//PhotoPreview 点击小图后的效果
  12 +class PhotoPreview extends StatefulWidget {
  13 + final int initialIndex;
  14 + final List<String> photoList;
  15 + final PageController pageController;
  16 + final bool isShow;
  17 + final List dashName;
  18 +
  19 + PhotoPreview({this.initialIndex, this.photoList, this.isShow, this.dashName})
  20 + : pageController = PageController(initialPage: initialIndex);
  21 +
  22 + @override
  23 + _PhotoPreviewState createState() => _PhotoPreviewState();
  24 +}
  25 +
  26 +class _PhotoPreviewState extends State<PhotoPreview> {
  27 + int currentIndex;
  28 + final _controller = new PageController();
  29 +
  30 + static const _kDuration = const Duration(milliseconds: 300);
  31 +
  32 + static const _kCurve = Curves.ease;
  33 +
  34 + final _kArrowColor = Colors.black.withOpacity(0.8);
  35 +
  36 + List tempImgList = [];
  37 +
  38 + @override
  39 + void initState() {
  40 + currentIndex = widget.initialIndex;
  41 +
  42 + for (var item in widget.photoList) {
  43 + tempImgList.add('$item-zdmask');
  44 + }
  45 + print(tempImgList);
  46 + // tempImgList = widget.photoList;
  47 + super.initState();
  48 + }
  49 +
  50 + //图片切换
  51 + void onPageChanged(int index) {
  52 + setState(() {
  53 + currentIndex = index;
  54 + });
  55 + }
  56 +
  57 + @override
  58 + Widget build(BuildContext context) {
  59 + return Material(
  60 + child: InkWell(
  61 + onTap: () {
  62 + Navigator.of(context).pop();
  63 + },
  64 + child: Container(
  65 + decoration: BoxDecoration(
  66 + color: Colors.black,
  67 + ),
  68 + constraints: BoxConstraints.expand(
  69 + height: MediaQuery.of(context).size.height,
  70 + ),
  71 + child: Stack(
  72 + children: <Widget>[
  73 + Container(
  74 + // width: ScreenUtil().setWidth(375 * 2),
  75 + // height: ScreenUtil().setHeight(397 * 2),
  76 + // margin: EdgeInsets.only(
  77 + // top: ScreenUtil().setWidth(260),
  78 + // bottom: ScreenUtil().setWidth(280)),
  79 + child: PhotoViewGallery.builder(
  80 + scrollPhysics: const BouncingScrollPhysics(),
  81 + onPageChanged: onPageChanged,
  82 + itemCount: tempImgList.length,
  83 + reverse: false,
  84 + loadingBuilder: (context, event) {
  85 + return UnconstrainedBox(
  86 + child: SizedBox(
  87 + width: ScreenUtil().setWidth(80),
  88 + height: ScreenUtil().setWidth(80),
  89 + child: CircularProgressIndicator(),
  90 + ),
  91 + );
  92 + },
  93 + pageController: widget.pageController,
  94 + builder: (BuildContext context, int index) {
  95 + return PhotoViewGalleryPageOptions(
  96 + imageProvider: NetworkImage(tempImgList[index]),
  97 + minScale: PhotoViewComputedScale.contained * 0.6,
  98 + maxScale: PhotoViewComputedScale.covered * 1.1,
  99 + initialScale: PhotoViewComputedScale.contained,
  100 + );
  101 + },
  102 + ),
  103 + ),
  104 + Positioned(
  105 + top: ScreenUtil().setWidth(70),
  106 + left: ScreenUtil().setWidth(40),
  107 + child: Icon(Icons.close, color: Colors.white)),
  108 + ],
  109 + )),
  110 + ));
  111 + }
  112 +}
  113 +
  114 +/// An indicator showing the currently selected page of a PageController
  115 +class DotsIndicator extends AnimatedWidget {
  116 + DotsIndicator({
  117 + this.controller,
  118 + this.itemCount,
  119 + this.onPageSelected,
  120 + this.color: Colors.white,
  121 + }) : super(listenable: controller);
  122 +
  123 + /// The PageController that this DotsIndicator is representing.
  124 + final PageController controller;
  125 +
  126 + /// The number of items managed by the PageController
  127 + final int itemCount;
  128 +
  129 + /// Called when a dot is tapped
  130 + final ValueChanged<int> onPageSelected;
  131 +
  132 + /// The color of the dots.
  133 + ///
  134 + /// Defaults to `Colors.white`.
  135 + final Color color;
  136 +
  137 + // The base size of the dots
  138 + static const double _kDotSize = 4.0;
  139 +
  140 + // The increase in the size of the selected dot
  141 + static const double _kMaxZoom = 2.0;
  142 +
  143 + // The distance between the center of each dot
  144 + static const double _kDotSpacing = 18.0;
  145 +
  146 + Widget _buildDot(int index) {
  147 + double selectedness = Curves.easeOut.transform(
  148 + max(
  149 + 0.0,
  150 + 1.0 - ((controller.page ?? controller.initialPage) - index).abs(),
  151 + ),
  152 + );
  153 + double zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness;
  154 +
  155 + return new Container(
  156 + width: _kDotSpacing,
  157 + child: new Center(
  158 + child: new Material(
  159 + color: color,
  160 + type: MaterialType.circle,
  161 + child: new Container(
  162 + width: _kDotSize * zoom,
  163 + height: _kDotSize * zoom,
  164 + child: new InkWell(
  165 + onTap: () => onPageSelected(index),
  166 + ),
  167 + ),
  168 + ),
  169 + ),
  170 + );
  171 + }
  172 +
  173 + Widget build(BuildContext context) {
  174 + return new Row(
  175 + mainAxisAlignment: MainAxisAlignment.center,
  176 + children: new List<Widget>.generate(itemCount, _buildDot),
  177 + );
  178 + }
  179 +}
@@ -22,6 +22,25 @@ import '../app.dart'; @@ -22,6 +22,25 @@ import '../app.dart';
22 typedef BookTimeSetCallback = void Function(bool needChange); 22 typedef BookTimeSetCallback = void Function(bool needChange);
23 23
24 class Utils { 24 class Utils {
  25 + static setBarStatus(bool isDarkIcon,
  26 + {Color color: Colors.transparent}) async {
  27 + if (Platform.isAndroid) {
  28 + if (isDarkIcon) {
  29 + SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
  30 + statusBarColor: color,
  31 + statusBarIconBrightness: Brightness.dark,
  32 + statusBarBrightness: Brightness.dark);
  33 + SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  34 + } else {
  35 + SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(
  36 + statusBarColor: color,
  37 + statusBarIconBrightness: Brightness.light,
  38 + statusBarBrightness: Brightness.light);
  39 + SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  40 + }
  41 + }
  42 + }
  43 +
25 static void showToast(String msg) { 44 static void showToast(String msg) {
26 Fluttertoast.showToast( 45 Fluttertoast.showToast(
27 msg: msg, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.CENTER); 46 msg: msg, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.CENTER);
@@ -667,6 +667,13 @@ packages: @@ -667,6 +667,13 @@ packages:
667 url: "https://pub.flutter-io.cn" 667 url: "https://pub.flutter-io.cn"
668 source: hosted 668 source: hosted
669 version: "3.0.4" 669 version: "3.0.4"
  670 + photo_view:
  671 + dependency: "direct main"
  672 + description:
  673 + name: photo_view
  674 + url: "https://pub.flutter-io.cn"
  675 + source: hosted
  676 + version: "0.9.2"
670 platform: 677 platform:
671 dependency: transitive 678 dependency: transitive
672 description: 679 description:
@@ -975,6 +982,27 @@ packages: @@ -975,6 +982,27 @@ packages:
975 url: "https://pub.flutter-io.cn" 982 url: "https://pub.flutter-io.cn"
976 source: hosted 983 source: hosted
977 version: "2.0.8" 984 version: "2.0.8"
  985 + video_player:
  986 + dependency: "direct main"
  987 + description:
  988 + name: video_player
  989 + url: "https://pub.flutter-io.cn"
  990 + source: hosted
  991 + version: "0.10.12+5"
  992 + video_player_platform_interface:
  993 + dependency: transitive
  994 + description:
  995 + name: video_player_platform_interface
  996 + url: "https://pub.flutter-io.cn"
  997 + source: hosted
  998 + version: "2.2.0"
  999 + video_player_web:
  1000 + dependency: transitive
  1001 + description:
  1002 + name: video_player_web
  1003 + url: "https://pub.flutter-io.cn"
  1004 + source: hosted
  1005 + version: "0.1.4+1"
978 watcher: 1006 watcher:
979 dependency: transitive 1007 dependency: transitive
980 description: 1008 description:
@@ -90,7 +90,9 @@ dependencies: @@ -90,7 +90,9 @@ dependencies:
90 easy_contact_picker: ^0.0.2 90 easy_contact_picker: ^0.0.2
91 flutter_app_badger: ^1.1.2 91 flutter_app_badger: ^1.1.2
92 scrollable_positioned_list: ^0.1.8 92 scrollable_positioned_list: ^0.1.8
93 - image_picker: 93 + image_picker: ^0.6.7+21
  94 + video_player: ^0.10.3
  95 + photo_view: ^0.9.2
94 #七牛云sdk 96 #七牛云sdk
95 # qiniu_flutter_sdk: ^0.1.0 97 # qiniu_flutter_sdk: ^0.1.0
96 98