PhotoTool.dart 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
  5. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  6. class PhotoTool extends StatefulWidget {
  7. @required final int imageCount;//最多几张
  8. @required final int lineCount;//一行几个
  9. @required final FocusNode focusNode;
  10. final _AddCall addCall;
  11. final _RemoveCall removeCall;
  12. //注:最好把图片和文字这些都拿出来,方便更改,这里就不搞了
  13. // const PhotoTool({required this.imageCount,required this.lineCount
  14. // ,required this.addCall,required this.removeCall});
  15. const PhotoTool({super.key, required this.imageCount,required this.lineCount
  16. ,required this.addCall,required this.removeCall,required this.focusNode});
  17. @override
  18. _PhotoToolState createState() => _PhotoToolState();
  19. }
  20. class _PhotoToolState extends State<PhotoTool> {
  21. static List<AssetEntity> _imageFiles = [];
  22. // var _event;
  23. @override
  24. Widget build(BuildContext context) {
  25. return Container(
  26. width: double.infinity,
  27. color: Colors.white,
  28. child: Padding(
  29. padding: const EdgeInsets.all(12.0),
  30. child: Column(
  31. crossAxisAlignment: CrossAxisAlignment.start,
  32. children: [
  33. RichText(
  34. text: TextSpan(
  35. text: '说明:',
  36. style: Theme.of(context).textTheme.subtitle2,
  37. children: [
  38. TextSpan(
  39. text: '(说明:上传图片,最多${widget.imageCount}张)',
  40. style: Theme.of(context)
  41. .textTheme
  42. .bodyText2
  43. ?.copyWith(color: Colors.grey),
  44. ),
  45. ],
  46. ),
  47. ),
  48. SizedBox(height: 16.0),
  49. StaggeredGridView.countBuilder(
  50. shrinkWrap: true,
  51. crossAxisCount: widget.lineCount,
  52. itemCount: _imageFiles.length == widget.imageCount
  53. ? _imageFiles.length
  54. : _imageFiles.length + 1,
  55. physics: NeverScrollableScrollPhysics(),
  56. itemBuilder: (BuildContext context, int index) {
  57. if (_imageFiles.length < widget.imageCount && index == 0) {
  58. return InkWell(
  59. onTap: () => _onPickImage(),
  60. child: Container(
  61. padding: EdgeInsets.all(5),
  62. child: Container(
  63. decoration: BoxDecoration(
  64. borderRadius: BorderRadius.circular(5.0),
  65. color: Color(0xFFF6F7F8),
  66. ),
  67. child: Center(
  68. child: Icon(
  69. Icons.add,
  70. color: Color(0xFFB4B4B4),
  71. size: 40,
  72. ),
  73. ),
  74. ),
  75. ),
  76. );
  77. } else {
  78. return Stack(
  79. children: [
  80. Container(
  81. padding: EdgeInsets.all(5),
  82. child: InkWell(
  83. child: FutureBuilder<File?>(
  84. future: _imageFiles[_imageFiles.length < widget.imageCount ? index - 1 : index].file,
  85. builder: (context, snapshot) {
  86. return snapshot.connectionState ==
  87. ConnectionState.done
  88. ? Container(
  89. decoration: BoxDecoration(
  90. shape: BoxShape.rectangle,
  91. borderRadius:
  92. BorderRadius.circular(6.0),
  93. image: DecorationImage(
  94. image: FileImage(File(snapshot.data!.path)),
  95. fit: BoxFit.cover,
  96. ),
  97. ),
  98. )
  99. : Container(
  100. decoration: BoxDecoration(
  101. shape: BoxShape.rectangle,
  102. borderRadius:
  103. BorderRadius.circular(6.0),
  104. color: Color(0xFFF6F7F8),
  105. ),
  106. child: Center(
  107. child: CupertinoActivityIndicator(),
  108. ),
  109. );
  110. },
  111. ),
  112. ),
  113. ),
  114. InkWell(
  115. onTap: () => _deleteImage(
  116. _imageFiles.length < widget.imageCount
  117. ? index - 1
  118. : index),
  119. child: Container(
  120. decoration: BoxDecoration(
  121. borderRadius: BorderRadius.circular(99.0),
  122. color: Colors.red,
  123. ),
  124. padding: EdgeInsets.all(2.0),
  125. child: Icon(
  126. Icons.close,
  127. size: 20.0,
  128. color: Colors.white,
  129. ),
  130. ),
  131. ),
  132. ],
  133. );
  134. }
  135. },
  136. staggeredTileBuilder: (int index) =>
  137. new StaggeredTile.count(1, 1),
  138. mainAxisSpacing: 4.0,
  139. crossAxisSpacing: 4.0,
  140. ),
  141. ],
  142. ),
  143. ),
  144. );
  145. }
  146. /// 选择图片
  147. _onPickImage() async {
  148. widget.focusNode.unfocus();
  149. List<AssetEntity>? assets = await AssetPicker.pickAssets(
  150. context,
  151. pickerConfig:AssetPickerConfig(maxAssets:widget.imageCount - _imageFiles.length,themeColor: Theme.of(context).primaryColor, requestType: RequestType.image,)
  152. );
  153. if (assets == null || assets.length <= 0) return;
  154. setState(() {
  155. _imageFiles.addAll(assets);
  156. if (widget.addCall != null) {
  157. widget.addCall(_imageFiles);
  158. }
  159. });
  160. }
  161. /// 删除图片
  162. _deleteImage(int index) {
  163. widget.focusNode.unfocus();
  164. if (_imageFiles == null || _imageFiles.length <= index) return;
  165. setState(() {
  166. _imageFiles.removeAt(index);
  167. if (widget.removeCall != null) {
  168. widget.removeCall(index);
  169. }
  170. });
  171. }
  172. // @override
  173. // void initState() {
  174. // super.initState();
  175. // _event = eventBus.on<RefreshPhoto>().listen((event) {
  176. // setState(() {
  177. // _imageFiles.addAll(event.imageFiles);
  178. // _imageFiles.addAll(widget.imageFiles);
  179. // });
  180. // });
  181. // }
  182. // @override
  183. // void dispose() {
  184. // super.dispose();
  185. // _event.cancel();
  186. // }
  187. }
  188. typedef _AddCall = void Function(List<AssetEntity> mList);
  189. typedef _RemoveCall = void Function(int index);