import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; import 'dart:ui' as ui; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:more_picture_share/more_picture_share.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:share_extend/share_extend.dart'; import 'package:sharesdk_plugin/sharesdk_plugin.dart'; import 'package:zhiying_base_widget/dialog/loading/loading.dart'; import 'package:zhiying_base_widget/utils/image_download_util/image_download_util.dart'; import 'package:zhiying_base_widget/widgets/share/models/share_alert_model.dart'; import 'package:zhiying_base_widget/widgets/share/models/share_data_model.dart'; import 'package:zhiying_base_widget/widgets/share/models/share_icon_model.dart'; import 'package:zhiying_base_widget/widgets/share/share_alert_content.dart'; import 'package:zhiying_comm/zhiying_comm.dart'; import 'package:zhiying_base_widget/widgets/share/models/share_select_pic_model.dart'; import 'package:zhiying_base_widget/template/goods_share_template/goods_share_template.dart'; class ShareAlertSelect extends StatefulWidget { final String skipIdentifier; final bool isContentShow; final ShareDataModel model; final bool isPicShow; final ShareSelectPicModel selectPicModel; const ShareAlertSelect(this.model, this.skipIdentifier, {Key key, this.isContentShow = false, this.selectPicModel, this.isPicShow}) : super(key: key); // 中间视图 @override _ShareAlertSelectState createState() => _ShareAlertSelectState(); } class _ShareAlertSelectState extends State { ShareAlertModel _iconModel; bool isPicShow; ShareSelectPicModel selectPicModel; GlobalKey _globalKey = GlobalKey(); List tempPoster; @override void initState() { NetUtil.request('/api/v1/mod/${widget.skipIdentifier}', method: NetMethod.GET, onCache: (data) { // try{ // _parseData(data); // }catch(e){ // print(e); // } }, onSuccess: (data) { print(data); _parseData(data); }, onError: (err) {}); if (!EmptyUtil.isEmpty(widget.isPicShow)) { isPicShow = widget.isPicShow; } else { isPicShow = false; } selectPicModel = widget.selectPicModel; super.initState(); } void _parseData(Map data) { List modList = data['mod_list']; Map d = modList.first; if (d != null) { String dString = d['data']; _iconModel = ShareAlertModel.fromJson(Map.from(jsonDecode(dString))); setState(() {}); } } _selectPic(List picList, int position) async { ShareDataModel model = ShareDataModel(); model.image = []; for (int i = 0; i < picList.length; i++) { if (picList[i].select) { if (i == 0) { if (tempPoster == null) { Loading.show(context); ShareDataModel shareDataModel = await _updateModel(_globalKey); tempPoster = shareDataModel.poster; model.poster = shareDataModel.poster; Loading.dismiss(); } else { model.poster = tempPoster; } } else { model.image.add(picList[i].pic); } } } EventUtil.instance.fire(model); } ///截图保存 Future _updateModel(GlobalKey _globalKey) async { ShareDataModel _shareModel = ShareDataModel(); BuildContext buildContext = _globalKey.currentContext; if (null != buildContext) { RenderRepaintBoundary boundary = buildContext.findRenderObject(); ///pixelRatio是放大倍数 ui.Image image = await boundary.toImage(pixelRatio: 5); // 注意:png是压缩后格式,如果需要图片的原始像素数据,请使用rawRgba ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png); Uint8List pngBytes = byteData.buffer.asUint8List(); _shareModel.poster = pngBytes; } else { _shareModel.poster = null; } // _shareModel.content = _isContentSelected ? _content : ''; return _shareModel; } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { Loading.dismiss(); Navigator.canPop(context); return true; }, child: GestureDetector( child: Scaffold( backgroundColor: Colors.transparent, body: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), //背景 child: Container( child: Column( children: [ widget.isContentShow ? Expanded( child: Center(child: ShareAlertContent(_iconModel)), ) : Container(), isPicShow ? Expanded( child: Swiper( loop: false, itemBuilder: (BuildContext context, int index) { Widget picWidget; if (index == 0) { picWidget = Column( children: [ Expanded( child: Transform.scale( alignment: Alignment.center, scale: 0.75, child: GoodsShareTemplate( selectPicModel.posterModel, contentKey: _globalKey, ), ), ), ], ); } else { picWidget = CachedNetworkImage( imageUrl: selectPicModel.picList[index].pic, fit: BoxFit.fitWidth, ); } return Container( alignment: Alignment.bottomCenter, margin: EdgeInsets.only(top: 50, bottom: 10), child: Stack( children: [ picWidget, // CachedNetworkImage( // imageUrl: selectPicModel.picList[index].pic, // fit: BoxFit.fitWidth, // ), Positioned( bottom: 10, right: 15, child: GestureDetector( onTap: () { selectPicModel.picList[index].select = !selectPicModel.picList[index].select; setState(() {}); _selectPic(selectPicModel.picList, index); }, child: Container( alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(50), color: selectPicModel.picList[index].select ? Colors.red : Colors.grey, ), child: Icon( CupertinoIcons.check_mark, color: Colors.white, ), ), ), ) ], ), ); }, itemCount: selectPicModel.picList.length, viewportFraction: 0.8, scale: 0.8, ), ) : Container(), _ShareAlertContent(widget.model, widget.skipIdentifier, _iconModel, isPicShow), ], ), ), // 模糊化 ), ), onTap: () { // Navigator.of(context).pop(); }, ), ); } } class _ShareAlertContent extends StatefulWidget { final ShareDataModel model; final String skipIdentifier; final ShareAlertModel iconModel; final bool isSelectPic; const _ShareAlertContent(this.model, this.skipIdentifier, this.iconModel, this.isSelectPic, {Key key}) : super(key: key); @override _ShareAlertContentState createState() => _ShareAlertContentState(); } class _ShareAlertContentState extends State<_ShareAlertContent> { StreamSubscription listen; bool isSelectPic; ShareDataModel _shareDataModel; @override void dispose() { // TODO: implement dispose listen?.cancel(); super.dispose(); } @override void initState() { // TODO: implement initState isSelectPic = widget.isSelectPic; if (isSelectPic) { _shareDataModel = null; } else { _shareDataModel = widget?.model; } listen = EventUtil.instance.on().listen((ShareDataModel event) { if (isSelectPic) { _shareDataModel = event; } }); super.initState(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () {}, child: Container( width: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(12), topRight: Radius.circular(12), ), ), child: SafeArea( top: false, child: Column( children: [ Container( margin: EdgeInsets.only(top: 8, bottom: 8), width: 62, height: 4, decoration: BoxDecoration(color: Color(0xffd8d8d8), borderRadius: BorderRadius.circular(2)), ), Text( '分享至', style: TextStyle(fontSize: 15, color: Color(0xff333333), fontWeight: FontWeight.bold), ), Container( margin: EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 10), child: _createIcons(), ), GestureDetector( child: Container( margin: EdgeInsets.only(left: 12, right: 12, bottom: 10), padding: EdgeInsets.all(12), decoration: BoxDecoration(color: Color(0xfff3f3f3), borderRadius: BorderRadius.circular(8)), child: Center( child: Text( '取消', style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold, color: Color(0xff999999)), ), ), ), onTap: () { Navigator.of(context).pop(); }, ) ], ), ), ), ); } Widget _createIcons() { return Wrap( spacing: 10, runSpacing: 10, children: widget.iconModel?.icons?.map((item) { return _createIcon(item); })?.toList() ?? [], ); } Widget _createIcon(ShareIconModel item) { return GestureDetector( child: Container( width: 60, child: Column( children: [ Container( width: 40, height: 40, child: CachedNetworkImage( imageUrl: item.icon, fit: BoxFit.contain, ), ), Padding( padding: const EdgeInsets.only(top: 2, bottom: 2), child: Text( item.name, style: TextStyle(fontSize: 12, color: Color(0xff333333), fontWeight: FontWeight.bold), ), ), ], ), ), onTap: () async { //检查是否有存储权限 var status = await Permission.storage.status; if (!status.isGranted) { status = await Permission.storage.request(); print(status); return; } Loading.show(context); ///检查是否选中图片 if (_shareDataModel?.poster == null && (_shareDataModel?.image == null || _shareDataModel?.image?.length == 0)) { Fluttertoast.showToast(msg: "请选择需要分享的图片"); Loading.dismiss(); return; } if (_shareDataModel?.poster != null) { File file = await EncodeUtil.compressImage(context, images: _shareDataModel?.poster, size: 400); _shareDataModel.poster = file.readAsBytesSync(); Loading.dismiss(); } int count = 0; if (_shareDataModel.poster != null) { count++; } count += (_shareDataModel?.image?.length ?? 0); // 多图分享 if (count > 1) { _shareMultipleImages(item.type); return; } if (item.type == 'wx') { _shareByMob(ShareSDKPlatforms.wechatSession); } else if (item.type == 'pyq') { _shareByMob(ShareSDKPlatforms.wechatTimeline); } else if (item.type == 'qq') { _shareByMob(ShareSDKPlatforms.qq); } else if (item.type == 'qq_space') { _shareByMob(ShareSDKPlatforms.qZone); } else if (item.type == 'weibo') { _shareByMob(ShareSDKPlatforms.sina); } else if (item.type == 'more_setting') { _shareBySystem(item.type); } }); } // mob分享,只能单图分享,多图分享调用系统分享 void _shareByMob(ShareSDKPlatform plateform) async { if (isSelectPic && EmptyUtil.isEmpty(_shareDataModel) && EmptyUtil.isEmpty(_shareDataModel?.poster) && EmptyUtil.isEmpty(_shareDataModel?.image)) { Fluttertoast.showToast(msg: '请选择分享图片'); return; } Loading.show(context); Timer(Duration(milliseconds: 2000), () { Loading.dismiss(); }); SSDKMap params; if (_shareDataModel.poster != null) { String path = await _savePoster(); if (path != null && path != '') { params = SSDKMap() ..setGeneral( _shareDataModel?.title ?? '', _shareDataModel?.content ?? '', Platform.isIOS ? path : null, null, Platform.isAndroid ? path : null, null, null, null, null, null, SSDKContentTypes.image, ); } } else { var type = SSDKContentTypes.auto; if (_shareDataModel?.image?.first != null && _shareDataModel?.url != null) { type = SSDKContentTypes.webpage; } else if (_shareDataModel?.image?.first != null) { type = SSDKContentTypes.image; } else if (_shareDataModel?.title != null || _shareDataModel?.content != null) { type = SSDKContentTypes.text; } if (plateform == ShareSDKPlatforms.qZone && type == SSDKContentTypes.text) { _shareDataModel?.title = null; type = SSDKContentTypes.message; } params = SSDKMap() ..setGeneral( _shareDataModel?.title ?? '', _shareDataModel?.content ?? '', Platform.isIOS ? _shareDataModel.image : null, Platform.isAndroid ? _shareDataModel?.image?.first : null, null, _shareDataModel.url, null, null, null, null, type, ); } SharesdkPlugin.share(plateform, params, (SSDKResponseState state, Map userdata, Map contentEntity, SSDKError error) { print(error); if (state == SSDKResponseState.Fail) { Fluttertoast.showToast(msg: '分享失败'); } else if (state == SSDKResponseState.Success) { //Fluttertoast.showToast(msg: '分享成功'); } else if (state == SSDKResponseState.Cancel) { Fluttertoast.showToast(msg: '取消分享'); } Logger.debug('${state}, ${error.rawData}'); Loading.dismiss(); }); } // 系统分享,只能分享图片或者文字,不能组合分享 void _shareBySystem(String type) async { if (isSelectPic && EmptyUtil.isEmpty(_shareDataModel) && EmptyUtil.isEmpty(_shareDataModel?.poster) && EmptyUtil.isEmpty(_shareDataModel?.image)) { Fluttertoast.showToast(msg: '请选择分享图片'); return; } int count = 0; if (_shareDataModel.poster != null) { count++; } count += (_shareDataModel?.image?.length ?? 0); // 多图分享 if (count > 1) { _shareMultipleImages(type); return; } if (_shareDataModel.poster != null) { String path = await _savePoster(); if (path != null && path != '') { ShareExtend.share(path, 'image'); } } else { ShareExtend.share(_shareDataModel.content, 'text'); } } Future _savePoster() async { String path; if (_shareDataModel.poster != null) { // 检查并请求权限 var status = await Permission.storage.status; if (status != PermissionStatus.granted) { status = await Permission.storage.request(); } if (status == PermissionStatus.denied) { Fluttertoast.showToast(msg: '暂无权限,分享失败'); return null; } try { // 保存到本地路径 final tempDir = await getTemporaryDirectory(); final file = await File('${tempDir.path}/image.jpg').create(); file.writeAsBytesSync(_shareDataModel.poster); path = file.path; Logger.debug(file.path); } catch (err, s) { Logger.error(err.toString(), s.toString()); Fluttertoast.showToast(msg: '分享失败'); return null; } } return path; } // 多图分享,调用系统分享 void _shareMultipleImages(String type) async { List paths = List(); String path = await _savePoster(); if (path != null && path != '') { paths.add(path); } Loading.show(context); List downPaths = await ImageDownloadUtil.download(_shareDataModel.image); paths.addAll(downPaths); if (Platform.isAndroid && type == 'wx') { MorePictureShare.shareWeixinPics(paths); } else if (Platform.isAndroid && type == 'pyq') { MorePictureShare.shareWeixinPicsCirlc(paths); } else { ShareExtend.shareMultiple(paths, "image", subject: ""); } Loading.dismiss(); } }