123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- import 'dart:ui';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/rendering.dart';
- import 'package:flutter/services.dart';
- import 'package:image_gallery_saver/image_gallery_saver.dart';
- import 'package:provider/provider.dart';
- import 'package:sport/bean/post.dart';
- import 'package:sport/pages/social/post_page.dart';
- import 'package:sport/pages/social/post_share_page.dart';
- import 'package:sport/provider/user_model.dart';
- import 'package:sport/router/navigator_util.dart';
- import 'package:sport/services/api/inject_api.dart';
- import 'package:sport/utils/toast.dart';
- import 'package:path_provider/path_provider.dart';
- import 'package:sport/sharesdk/tencent.dart';
- import 'package:sport/sharesdk/wechat.dart';
- import 'package:sport/widgets/space.dart';
- import 'dart:io';
- import 'dart:typed_data';
- import 'package:wechat_kit/wechat_kit.dart';
- class MenuShareBottomContent extends StatefulWidget {
- final String url; // 复制的那个链接
- final bool hasDownload; // 有些又download 有些没download
- final GlobalKey poster; // 下载海报...
- final String shareType; // 什么类型 Img social Link
- final Post post; // social 连带的 post
- final String hash; // 分享 link 连带的hash
- MenuShareBottomContent(
- this.shareType, {
- this.post,
- this.url = "",
- this.hasDownload = false,
- this.poster,
- this.hash,
- });
- @override
- State<StatefulWidget> createState() {
- // TODO: implement createState
- return _MenuShareBottomContentState();
- }
- }
- // shareType : Img / Link / Social
- class _MenuShareBottomContentState extends State<MenuShareBottomContent>
- with TencentMixin, WechatMixin, InjectApi {
- List<Map<String, dynamic>> map;
- Uint8List postInstance;
- @override
- listenShareMsg(WechatSdkResp resp) {
- Navigator.pop(context);
- ToastUtil.show("分享成功");
- }
- @override
- void initState() {
- // TODO: implement initState
- super.initState();
- map = [
- {
- "value": "微信",
- "url": "share_icon_wechat",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- wechatShareImage(path, "chat");
- } else if (widget.shareType == "Link") {
- wechatShareLink(widget.url + "?h=${widget.hash}", "chat",
- Provider.of<UserModel>(context, listen: false).user.name);
- }
- }
- },
- {
- "value": "朋友圈",
- "url": "share_icon_wechatmonents",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- wechatShareImage(path, "friend");
- } else if (widget.shareType == "Link") {
- wechatShareLink(widget.url + "?h=${widget.hash}", "friend",
- Provider.of<UserModel>(context, listen: false).user.name);
- }
- }
- },
- {
- "value": "QQ",
- "url": "share_icon_qq",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- qqShare(path);
- } else if (widget.shareType == "Link") {
- qqShareLink(widget.url);
- }
- }
- },
- {
- "value": "社区",
- "url": "share_icon_community",
- "callBack": () async {
- if (widget.shareType == "social") {
- await NavigatorUtil.goPage(
- context,
- (contxt) => PostPage(
- "",
- post: widget.post,
- ));
- } else if (widget.shareType == "Link") {
- await NavigatorUtil.goPage(
- context,
- (contxt) => PostPage(
- "",
- post: widget.post,
- url: "http://shoes-web.hiyd.com/share",
- hash: widget.hash,
- ));
- } else if (widget.shareType == "Img") {
- String path = await initFile();
- print("$path---------------------------------");
- Future.delayed(new Duration(milliseconds: 200));
- await NavigatorUtil.goPage(
- context, (context) => PostPage("",image: path));
- }
- Navigator.pop(context, true);
- }
- },
- {
- "value": "社区好友",
- "url": "share_icon_friends",
- "callBack": () async {
- if (widget.shareType == "social") {
- await NavigatorUtil.goPage(
- context,
- (context) => PostShareFriendsPage(
- post: widget.post,
- ));
- } else if (widget.shareType == "Link") {
- // 这里可能得组装一手 link 的 数据 ...
- await NavigatorUtil.goPage(
- context, (context) => PostShareFriendsPage(hash: widget.hash));
- } else if (widget.shareType == "Img") {
- String path = await initFile();
- String url = (await api.postChatUpload(File(path))).data["url"];
- await NavigatorUtil.goPage(
- context,
- (context) => PostShareFriendsPage(
- image: url,
- ));
- }
- Navigator.pop(context, true);
- }
- },
- {
- "value": "复制链接",
- "url": "share_icon_link",
- "callBack": () {
- Clipboard.setData(ClipboardData(text: widget.url));
- ToastUtil.show("复制成功");
- }
- },
- {
- "value": "下载图片",
- "url": "share_icon_download",
- "callBack": () {
- _capture().then((file) async {}).whenComplete(() {
- print("Complete-------------------------------------------------");
- });
- }
- },
- ];
- if (widget.hasDownload == null || !widget.hasDownload) {
- map.removeLast();
- }
- if (widget.url == null) {
- map.removeAt(5);
- }
- // 社区暂时先把前面的隐藏掉
- if (widget.shareType == "social") {
- map = map.sublist(map.length - 2, map.length);
- }
- }
- // 封装成灵活的更通用一点...
- Future<String> initFile() async {
- Uint8List pngBytes = await initFileUint8List();
- print("$pngBytes------------------------------");
- String sTempDir = (await getTemporaryDirectory()).path;
- bool isDirExist = await Directory(sTempDir).exists();
- if (!isDirExist) {
- Directory(sTempDir).create();
- }
- // QQ分享需要一个确实存在的图片
- File file = await File(sTempDir +
- "/poster-temp-${DateTime.now().millisecondsSinceEpoch}.png")
- .writeAsBytes(pngBytes);
- print(
- "[file]:${file.readAsBytesSync().length}---------------${pngBytes.length}----------------");
- return file.path;
- }
- Future<Uint8List> initFileUint8List() async {
- try {
- RenderRepaintBoundary boundary =
- widget.poster.currentContext.findRenderObject();
- //boundary.toImage()转化为ui.Image对象,不会自动为包裹的组件添加背景,不设置可能会缺失背景
- var image = await boundary.toImage(pixelRatio: window.devicePixelRatio);
- //将image转化为byteData
- ByteData byteData = await image.toByteData(format: ImageByteFormat.png);
- //这个对象就是图片数据
- Uint8List pngBytes = byteData.buffer.asUint8List();
- print("成功生成图片 ----------------------------------------");
- return pngBytes;
- } catch (e) {
- print(e);
- }
- return null;
- }
- Future<File> _capture() async {
- Uint8List pngBytes = await initFileUint8List();
- final result = await ImageGallerySaver.saveImage(pngBytes); //这个是核心的保存图片的插件
- print(result);
- ToastUtil.show("下载成功");
- }
- @override
- Widget build(BuildContext context) {
- // TODO: implement build
- return SizedBox(
- child: Container(
- margin: EdgeInsets.fromLTRB(24, 23, 24, 17),
- child: Column(
- children: <Widget>[
- Row(
- children: <Widget>[
- Expanded(
- child: Divider(
- endIndent: 12.0,
- ),
- ),
- Text(
- "分享至",
- style: Theme.of(context).textTheme.bodyText2,
- ),
- Expanded(
- child: Divider(
- indent: 12.0,
- ),
- )
- ],
- ),
- SizedBox(
- height: 12.0,
- ),
- Expanded(
- child: GridView(
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 4,
- crossAxisSpacing: 12.0,
- mainAxisSpacing: 18.0),
- children: map
- .map(
- (e) => InkWell(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: <Widget>[
- Image.asset(
- "lib/assets/img/${e["url"]}.png",
- width: 44.0,
- height: 44.0,
- ),
- Space(
- height: 6.0,
- ),
- Text(
- "${e["value"]}",
- style: Theme.of(context).textTheme.subtitle2,
- ),
- // Space(height: 8.0,),
- ],
- ),
- onTap: () {
- e["callBack"]();
- },
- ),
- )
- .toList()),
- )
- ],
- ),
- ),
- height: 232.0,
- );
- }
- }
- Future<bool> menuShareBottom(BuildContext context, String shareType,
- {Post post, String url, bool hasDownload, GlobalKey poster, String hash}) {
- return showModalBottomSheet(
- context: context,
- builder: (context) {
- return MenuShareBottomContent(shareType,
- post: post,
- url: url,
- hasDownload: hasDownload,
- poster: poster,
- hash: hash);
- },
- backgroundColor: Colors.white,
- elevation: 10,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(10), topRight: Radius.circular(10)),
- ),
- );
- }
|