|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'dart:io';
|
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
|
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
|
import 'package:one_key/models/upload_img_model.dart';
|
|
|
|
import 'package:one_key/pages/online_check/photo_view_wiget.dart';
|
|
|
|
import 'package:one_key/pages/online_check/progress.dart';
|
|
|
|
|
|
|
|
import 'package:one_key/provider/online_check_edit_provider.dart';
|
|
|
|
import 'package:one_key/provider/upload_img_provider.dart';
|
|
|
|
import 'package:one_key/res/colors.dart';
|
|
|
|
import 'package:one_key/utils/dialog_util.dart';
|
|
|
|
import 'package:one_key/utils/misc.dart';
|
|
|
|
import 'package:one_key/utils/navigator_util.dart';
|
|
|
|
import 'package:one_key/utils/upload_image_util.dart';
|
|
|
|
import 'package:one_key/utils/utils.dart';
|
|
|
|
import 'package:one_key/widgets/MyDivider.dart';
|
|
|
|
import 'package:one_key/widgets/v_empty_view.dart';
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
|
|
import 'package:photo/photo.dart';
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
|
|
|
|
import 'package:image_picker/image_picker.dart';
|
|
|
|
import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
|
|
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
import '../online_check/dispose.dart';
|
|
|
|
import 'package:photo_manager/photo_manager.dart';
|
|
|
|
// import 'package:video_thumbnail/video_thumbnail.dart';
|
|
|
|
import 'package:chewie/chewie.dart';
|
|
|
|
|
|
|
|
typedef void OnPickImageCallback(
|
|
|
|
double maxWidth, double maxHeight, int quality);
|
|
|
|
|
|
|
|
class VideoPickerWidget extends StatefulWidget {
|
|
|
|
final ScrollController scrollController;
|
|
|
|
final Color borderColor;
|
|
|
|
final ValueChanged onChange;
|
|
|
|
final int maxImageNumber;
|
|
|
|
VideoPickerWidget(
|
|
|
|
{Key key,
|
|
|
|
this.scrollController,
|
|
|
|
this.borderColor = Colors.blue,
|
|
|
|
this.onChange,
|
|
|
|
this.maxImageNumber = 5})
|
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
_VideoPickerWidgetState createState() => _VideoPickerWidgetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _VideoPickerWidgetState extends DisposableState<VideoPickerWidget> {
|
|
|
|
final picker = ImagePicker();
|
|
|
|
// OnlineCheckEditProvider _onlineCheckEditProvider;
|
|
|
|
UploadImageProvider _uploadImageProvider;
|
|
|
|
|
|
|
|
// 用户输入的文件名
|
|
|
|
String key;
|
|
|
|
// 用户输入的 partSize
|
|
|
|
int partSize = 4;
|
|
|
|
// 用户输入的 token
|
|
|
|
String token;
|
|
|
|
|
|
|
|
/// storage 实例
|
|
|
|
final Storage storage = Storage();
|
|
|
|
// 控制器,可以用于取消任务、获取上述的状态,进度等信息
|
|
|
|
// PutController putController = PutController();
|
|
|
|
// 当前的任务状态
|
|
|
|
|
|
|
|
// String thumbnailPath;
|
|
|
|
VideoPlayerController _controller;
|
|
|
|
Future _initializeVideoPlayerFuture;
|
|
|
|
|
|
|
|
// 声明控制器(两个)
|
|
|
|
VideoPlayerController videoPlayerController;
|
|
|
|
ChewieController chewieController;
|
|
|
|
IjkMediaController ijkMediaController = IjkMediaController();
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
// storage = Storage();
|
|
|
|
// putController = PutController();
|
|
|
|
super.initState();
|
|
|
|
|
|
|
|
// _controller.setLooping(false);
|
|
|
|
// 生成控制器(两个)
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
super.dispose();
|
|
|
|
// 销毁播放器的控制器
|
|
|
|
_controller.dispose();
|
|
|
|
chewieController.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
///#相机拍照,单图选择
|
|
|
|
Future _getFromPictureOrCamera(imageSource) async {
|
|
|
|
final pickedFile = await picker.getVideo(
|
|
|
|
source: imageSource, maxDuration: const Duration(seconds: 15));
|
|
|
|
// thumbnailPath = await VideoThumbnail.thumbnailFile(
|
|
|
|
// video: pickedFile.path,
|
|
|
|
// imageFormat: ImageFormat.PNG,
|
|
|
|
// maxWidth: 128,
|
|
|
|
// quality: 25);
|
|
|
|
|
|
|
|
// print(thumbnailPath);
|
|
|
|
_controller = VideoPlayerController.file(File(pickedFile.path));
|
|
|
|
_initializeVideoPlayerFuture = _controller.initialize();
|
|
|
|
setState(() {
|
|
|
|
if (pickedFile != null) {
|
|
|
|
UploadImgModel imgModel = UploadImgModel();
|
|
|
|
imgModel.file = File(pickedFile.path);
|
|
|
|
imgModel.process = 0.01;
|
|
|
|
_uploadImageProvider.imageList.add(imgModel);
|
|
|
|
} else {
|
|
|
|
print('No image selected.');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (pickedFile != null) {
|
|
|
|
UploadImageUtil().startUpload(
|
|
|
|
context,
|
|
|
|
File(pickedFile.path),
|
|
|
|
_uploadImageProvider.imageList.length - 1,
|
|
|
|
true,
|
|
|
|
_uploadImageProvider);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///多图片选择
|
|
|
|
void pickAsset(PickType type, {List<AssetPathEntity> pathList}) async {
|
|
|
|
/// context is required, other params is optional.
|
|
|
|
List<AssetEntity> imgList = await PhotoPicker.pickAsset(
|
|
|
|
// BuildContext required
|
|
|
|
context: context,
|
|
|
|
|
|
|
|
/// The following are optional parameters.
|
|
|
|
themeColor: MyColours.color_199095,
|
|
|
|
// the title color and bottom color
|
|
|
|
textColor: Colors.white,
|
|
|
|
// text color
|
|
|
|
padding: 1.0,
|
|
|
|
// item padding
|
|
|
|
dividerColor: Colors.grey,
|
|
|
|
// divider color
|
|
|
|
disableColor: Colors.grey.shade300,
|
|
|
|
// the check box disable color
|
|
|
|
itemRadio: 0.88,
|
|
|
|
// the content item radio
|
|
|
|
maxSelected:
|
|
|
|
widget.maxImageNumber - _uploadImageProvider.imageList.length,
|
|
|
|
// max picker image count
|
|
|
|
// provider: I18nProvider.english,
|
|
|
|
provider: I18nProvider.chinese,
|
|
|
|
// i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
|
|
|
|
rowCount: 3,
|
|
|
|
// item row count
|
|
|
|
thumbSize: 150,
|
|
|
|
// preview thumb size , default is 64
|
|
|
|
sortDelegate: SortDelegate.common,
|
|
|
|
// default is common ,or you make custom delegate to sort your gallery
|
|
|
|
checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
|
|
|
|
activeColor: MyColours.color_353535,
|
|
|
|
unselectedColor: Colors.white,
|
|
|
|
checkColor: MyColours.color_199095,
|
|
|
|
),
|
|
|
|
// default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
|
|
|
|
// loadingDelegate: this,
|
|
|
|
// if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart]
|
|
|
|
badgeDelegate: const DurationBadgeDelegate(),
|
|
|
|
// badgeDelegate to show badge widget
|
|
|
|
pickType: type,
|
|
|
|
photoPathList: pathList,
|
|
|
|
);
|
|
|
|
if (imgList == null || imgList.isEmpty) {
|
|
|
|
print("No pick item.");
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < imgList.length; i++) {
|
|
|
|
var file = await imgList[i].file;
|
|
|
|
setState(() {
|
|
|
|
UploadImgModel imgModel = UploadImgModel();
|
|
|
|
imgModel.file = File(file.absolute.path);
|
|
|
|
imgModel.process = 0.01;
|
|
|
|
_uploadImageProvider.imageList.add(imgModel);
|
|
|
|
});
|
|
|
|
UploadImageUtil().startUpload(
|
|
|
|
context,
|
|
|
|
File(file.absolute.path),
|
|
|
|
_uploadImageProvider.imageList.length - 1,
|
|
|
|
false,
|
|
|
|
_uploadImageProvider);
|
|
|
|
// startUpload(File(file.absolute.path),
|
|
|
|
// _uploadImageProvider.imageList.length - 1, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
///添加图片UI弹出
|
|
|
|
Future _openModalBottomSheet(context) async {
|
|
|
|
final option = await showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
isDismissible: false,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return Container(
|
|
|
|
// height: ScreenUtil().setWidth(180 * 2),
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
color: MyColours.color_ffffff,
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
topLeft: Radius.circular(ScreenUtil().setWidth(24)),
|
|
|
|
topRight: Radius.circular(ScreenUtil().setWidth(24)))),
|
|
|
|
child: Column(
|
|
|
|
mainAxisSize: MainAxisSize.min,
|
|
|
|
children: <Widget>[
|
|
|
|
InkWell(
|
|
|
|
onTap: () {
|
|
|
|
Utils.getPickPermission(context, () {
|
|
|
|
_getFromPictureOrCamera(ImageSource.camera);
|
|
|
|
Navigator.pop(context);
|
|
|
|
}, PermissionGroup.camera);
|
|
|
|
},
|
|
|
|
child: Container(
|
|
|
|
width: double.infinity,
|
|
|
|
height: ScreenUtil().setWidth(58 * 2),
|
|
|
|
child: Center(
|
|
|
|
child: Text(
|
|
|
|
'拍摄',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: ScreenUtil().setSp(32),
|
|
|
|
color: MyColours.color_353535,
|
|
|
|
fontWeight: FontWeight.bold),
|
|
|
|
),
|
|
|
|
)),
|
|
|
|
),
|
|
|
|
MyDivider(
|
|
|
|
double.infinity,
|
|
|
|
ScreenUtil().setWidth(2),
|
|
|
|
color: MyColours.color_EEEEEE,
|
|
|
|
),
|
|
|
|
InkWell(
|
|
|
|
onTap: () {
|
|
|
|
Utils.getPickPermission(context, () {
|
|
|
|
// pickAsset(PickType.onlyVideo);
|
|
|
|
_getFromPictureOrCamera(ImageSource.gallery);
|
|
|
|
Navigator.pop(context);
|
|
|
|
}, PermissionGroup.photos);
|
|
|
|
},
|
|
|
|
child: Container(
|
|
|
|
width: double.infinity,
|
|
|
|
height: ScreenUtil().setWidth(58 * 2),
|
|
|
|
child: Center(
|
|
|
|
child: Text(
|
|
|
|
'从相册选择',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: ScreenUtil().setSp(32),
|
|
|
|
color: MyColours.color_353535,
|
|
|
|
fontWeight: FontWeight.bold),
|
|
|
|
),
|
|
|
|
)),
|
|
|
|
),
|
|
|
|
MyDivider(
|
|
|
|
double.infinity,
|
|
|
|
ScreenUtil().setWidth(10),
|
|
|
|
color: MyColours.color_EEEEEE,
|
|
|
|
),
|
|
|
|
InkWell(
|
|
|
|
onTap: () {
|
|
|
|
Navigator.pop(context, '取消');
|
|
|
|
},
|
|
|
|
child: Container(
|
|
|
|
width: double.infinity,
|
|
|
|
height: ScreenUtil().setWidth(58 * 2),
|
|
|
|
child: Center(
|
|
|
|
child: Text(
|
|
|
|
'取消',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: ScreenUtil().setSp(32),
|
|
|
|
color: MyColours.color_353535,
|
|
|
|
fontWeight: FontWeight.bold),
|
|
|
|
),
|
|
|
|
)))
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
//查看大图
|
|
|
|
_showPhotoView(BuildContext context, int index, List imgs,
|
|
|
|
{isShow = false, List dashName}) async {
|
|
|
|
// if (imgs.length == 1 &&
|
|
|
|
// imgs[0] ==
|
|
|
|
// 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {
|
|
|
|
// imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';
|
|
|
|
// }
|
|
|
|
// _controller = VideoPlayerController.network(imgs[index]);
|
|
|
|
// chewieController = ChewieController(
|
|
|
|
// videoPlayerController: _controller,
|
|
|
|
// // 比例
|
|
|
|
// // aspectRatio: 16 / 9,
|
|
|
|
// // 自动播放
|
|
|
|
// autoPlay: true,
|
|
|
|
// // 循环
|
|
|
|
// looping: true,
|
|
|
|
// );
|
|
|
|
|
|
|
|
ijkMediaController.setNetworkDataSource(
|
|
|
|
imgs[index],
|
|
|
|
autoPlay: true,
|
|
|
|
);
|
|
|
|
Utils.setBarStatus(false, color: Colors.black);
|
|
|
|
dynamic result = await showGeneralDialog(
|
|
|
|
context: context,
|
|
|
|
barrierDismissible: false,
|
|
|
|
barrierColor: Colors.black,
|
|
|
|
barrierLabel:
|
|
|
|
MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
|
|
|
transitionDuration: const Duration(milliseconds: 150),
|
|
|
|
pageBuilder: (BuildContext context, Animation animation,
|
|
|
|
Animation secondaryAnimation) {
|
|
|
|
return Column(
|
|
|
|
children: [
|
|
|
|
Container(
|
|
|
|
height: ScreenUtil().setWidth(100),
|
|
|
|
color: Colors.black,
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
Material(
|
|
|
|
child: InkWell(
|
|
|
|
onTap: () {
|
|
|
|
Navigator.pop(context);
|
|
|
|
},
|
|
|
|
child: Image.asset(Utils.getImgPath('invication_back')),
|
|
|
|
)),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|
|
|
|
// Chewie(
|
|
|
|
// controller: chewieController,
|
|
|
|
// ),
|
|
|
|
IjkPlayer(mediaController: ijkMediaController),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
// Utils.setBarStatus(true, color: Colors.white);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
_uploadImageProvider =
|
|
|
|
Provider.of<UploadImageProvider>(context, listen: true);
|
|
|
|
return _getGridImg(
|
|
|
|
_uploadImageProvider.imageList.length < widget.maxImageNumber
|
|
|
|
? _uploadImageProvider.imageList.length + 1
|
|
|
|
: _uploadImageProvider.imageList.length,
|
|
|
|
context,
|
|
|
|
_uploadImageProvider.imageList.length == widget.maxImageNumber
|
|
|
|
? true
|
|
|
|
: false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 九宫格
|
|
|
|
Widget _getGridImg(count, context, isLinjie) {
|
|
|
|
// return
|
|
|
|
// GridView.builder(
|
|
|
|
// controller: widget.scrollController,
|
|
|
|
// // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
|
|
|
|
// shrinkWrap: true,
|
|
|
|
// itemCount: count,
|
|
|
|
// //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
|
|
|
|
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
// //横轴元素个数
|
|
|
|
// crossAxisCount: 1,
|
|
|
|
// //纵轴间距
|
|
|
|
// mainAxisSpacing: ScreenUtil().setWidth(30),
|
|
|
|
// //横轴间距
|
|
|
|
// crossAxisSpacing: ScreenUtil().setWidth(30),
|
|
|
|
// //子组件宽高长度比例
|
|
|
|
// // childAspectRatio: 1.0
|
|
|
|
// ),
|
|
|
|
// itemBuilder: (BuildContext context, int index) {
|
|
|
|
//Widget Function(BuildContext context, int index)
|
|
|
|
var linjie = widget.maxImageNumber;
|
|
|
|
if (isLinjie) {
|
|
|
|
linjie = widget.maxImageNumber - 1;
|
|
|
|
}
|
|
|
|
if (0 == count - 1 && 0 < linjie) {
|
|
|
|
return InkWell(
|
|
|
|
onTap: () {
|
|
|
|
// 触摸收起键盘
|
|
|
|
FocusScope.of(context).requestFocus(FocusNode());
|
|
|
|
_openModalBottomSheet(context);
|
|
|
|
},
|
|
|
|
child: Container(
|
|
|
|
width: ScreenUtil().setWidth(90 * 2),
|
|
|
|
height: ScreenUtil().setWidth(90 * 2),
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
border: Border.all(
|
|
|
|
color: MyColours.color_E0E0E0,
|
|
|
|
width: ScreenUtil().setWidth(2)),
|
|
|
|
),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
VEmptyView(74),
|
|
|
|
Image.asset(
|
|
|
|
Utils.getImgPath('add_image'),
|
|
|
|
width: ScreenUtil().setWidth(32),
|
|
|
|
height: ScreenUtil().setWidth(32),
|
|
|
|
),
|
|
|
|
VEmptyView(10),
|
|
|
|
Text(
|
|
|
|
'添加视频',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: ScreenUtil().setSp(24),
|
|
|
|
color: MyColours.color_999999),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return _uploadImageProvider.imageList.length < 1
|
|
|
|
? Text('')
|
|
|
|
: InkWell(
|
|
|
|
onTap: () {
|
|
|
|
if (_uploadImageProvider.imageList[0].process == 1) {
|
|
|
|
_uploadImageProvider.imageQiniuUrlList = [];
|
|
|
|
if (_uploadImageProvider.imageList[0].qiniuUrl != null) {
|
|
|
|
for (int i = 0;
|
|
|
|
i < _uploadImageProvider.imageList.length;
|
|
|
|
i++) {
|
|
|
|
_uploadImageProvider.imageQiniuUrlList
|
|
|
|
.add(_uploadImageProvider.imageList[i].qiniuUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
///没有上传完成的不可以点击
|
|
|
|
// _showPhotoView(
|
|
|
|
// context, 0, _uploadImageProvider.imageQiniuUrlList);
|
|
|
|
NavigatorUtil.goPlayVideoPage(context,
|
|
|
|
urlStr: _uploadImageProvider.imageQiniuUrlList[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
child: Stack(
|
|
|
|
children: [
|
|
|
|
Stack(
|
|
|
|
alignment: Alignment.topRight,
|
|
|
|
children: [
|
|
|
|
// Image.file(
|
|
|
|
// // _uploadImageProvider.imageList[index].file,
|
|
|
|
// File(thumbnailPath),
|
|
|
|
// fit: BoxFit.cover,
|
|
|
|
// width: ScreenUtil().setWidth(100 * 2),
|
|
|
|
// height: ScreenUtil().setWidth(100 * 2),
|
|
|
|
// ),
|
|
|
|
FutureBuilder(
|
|
|
|
//显示缩略图
|
|
|
|
future: _initializeVideoPlayerFuture,
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
print(snapshot.connectionState);
|
|
|
|
if (snapshot.hasError) print(snapshot.error);
|
|
|
|
if (snapshot.connectionState == ConnectionState.done) {
|
|
|
|
return Container(
|
|
|
|
width: ScreenUtil().setWidth(225),
|
|
|
|
child: AspectRatio(
|
|
|
|
// aspectRatio: 1 / 1,
|
|
|
|
aspectRatio: _controller.value.aspectRatio,
|
|
|
|
child: VideoPlayer(_controller),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return Center(
|
|
|
|
child: CircularProgressIndicator(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
),
|
|
|
|
|
|
|
|
Offstage(
|
|
|
|
offstage: _uploadImageProvider.imageList[0].process < 1,
|
|
|
|
child: GestureDetector(
|
|
|
|
child: Image.asset(
|
|
|
|
Utils.getImgPath("delete"),
|
|
|
|
width: ScreenUtil().setWidth(40),
|
|
|
|
height: ScreenUtil().setWidth(40),
|
|
|
|
),
|
|
|
|
onTap: () {
|
|
|
|
//点击删除按钮
|
|
|
|
setState(() {
|
|
|
|
_uploadImageProvider.imageList.removeWhere(
|
|
|
|
(element) =>
|
|
|
|
element ==
|
|
|
|
_uploadImageProvider.imageList[0]);
|
|
|
|
_uploadImageProvider.imageQiniuUrlList.removeWhere(
|
|
|
|
(element) =>
|
|
|
|
element ==
|
|
|
|
_uploadImageProvider.imageQiniuUrlList[0]);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
Offstage(
|
|
|
|
offstage: _uploadImageProvider.imageList[0].process == 1,
|
|
|
|
child: Progress(_uploadImageProvider.imageList[0].process),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
));
|
|
|
|
// });
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|