123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- import 'dart:io';
- import 'dart:typed_data';
- import 'dart:ui' as ui;
- import 'package:flutter/material.dart';
- import 'package:flutter/rendering.dart';
- import 'package:image_gallery_saver/image_gallery_saver.dart';
- import 'package:path_provider/path_provider.dart';
- import 'package:sport/bean/jog/detail.dart';
- import 'package:sport/pages/home/home_info_page.dart';
- import 'package:sport/pages/run/run_share_long.dart';
- import 'package:sport/pages/run/run_share_simple.dart';
- import 'package:sport/utils/toast.dart';
- import 'package:sport/widgets/appbar.dart';
- import 'package:sport/widgets/button_primary.dart';
- import 'package:sport/widgets/dialog/request_dialog.dart';
- import 'package:sport/widgets/menu_share_bottom.dart';
- class RunShare extends StatefulWidget {
- final JogDetail detail;
- final File map;
- const RunShare({Key? key, required this.detail, required this.map}) : super(key: key);
- @override
- State<StatefulWidget> createState() {
- return _PageState();
- }
- }
- class _PageState extends State<RunShare> with SingleTickerProviderStateMixin {
- GlobalKey repaintKeySimple = GlobalKey();
- GlobalKey repaintKeyLong = GlobalKey();
- late TabController _controller;
- int index = 0;
- @override
- void initState() {
- _controller = TabController(length: 2, vsync: this)
- ..addListener(() {
- index = _controller.animation?.value.toInt() ?? 0;
- });
- super.initState();
- }
- @override
- void dispose() {
- _controller.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- backgroundColor: Colors.white,
- appBar: buildAppBar(context, title: "运动分享"),
- body: DefaultTabController(
- length: 2,
- child: Column(
- children: [
- Padding(
- padding: const EdgeInsets.all(12.0),
- child: indexTabBar(["图片", "长图"], tabController: _controller, fontSize: 14.0, padding: 0.0),
- ),
- Expanded(
- child: TabBarView(
- controller: _controller,
- children: <Widget>[
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
- child: RunShareSimple(
- detail: widget.detail,
- map: widget.map,
- repaintWidgetKey: repaintKeySimple,
- ),
- ),
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
- child: RunShareLongPage(
- detail: widget.detail,
- map: widget.map,
- repaintWidgetKey: repaintKeyLong,
- ),
- ),
- ],
- )),
- Padding(
- padding: const EdgeInsets.all(12.0),
- child: Row(
- children: [
- Expanded(
- child: GestureDetector(
- onTap: () {
- runShare(context, index, index == 0 ? repaintKeySimple : repaintKeyLong, true);
- },
- child: Container(
- height: 44,
- decoration: BoxDecoration(border: Border.all(color: Theme.of(context).accentColor, width: 1), borderRadius: BorderRadius.circular(50)),
- child: Center(
- child: Text(
- "保存",
- style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Theme.of(context).accentColor, fontSize: 16.0),
- strutStyle: StrutStyle(height: 1.1),
- ),
- ),
- ),
- )),
- const SizedBox(
- width: 20.0,
- ),
- Expanded(
- child: PrimaryButton(
- height: 44.0,
- callback: () {
- runShare(context, index, index == 0 ? repaintKeySimple : repaintKeyLong, false);
- },
- content: "分享",
- )),
- ],
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
- _takePicture(int index, GlobalKey key) async {
- try {
- RenderObject? boundary = key.currentContext?.findRenderObject();
- if (!(boundary is RenderRepaintBoundary)) return;
- double dpr = ui.window.devicePixelRatio; // 获取当前设备的像素比
- ui.Image image = await boundary.toImage(pixelRatio: dpr);
- ui.PictureRecorder pictureRecorder = new ui.PictureRecorder(); // 图片记录仪
- Canvas canvas = new Canvas(pictureRecorder); //canvas接受一个图片
- canvas.drawColor(Colors.white, BlendMode.clear);
- Paint _paint = new Paint()..isAntiAlias = true;
- canvas.drawImage(image, Offset(0, 0), _paint);
- ui.Image picture = await pictureRecorder.endRecording().toImage(image.width, image.height); //设置生成图片的宽和高
- ByteData? pngImageBytes = await picture.toByteData(format: ui.ImageByteFormat.png);
- if (pngImageBytes == null) return;
- Uint8List pngBytes = pngImageBytes.buffer.asUint8List();
- String sTempDir = (await getTemporaryDirectory()).path;
- bool isDirExist = await Directory(sTempDir).exists();
- if (!isDirExist) {
- Directory(sTempDir).create();
- }
- File file = await File(sTempDir + "/poster-temp-${DateTime.now().millisecondsSinceEpoch}.png").writeAsBytes(pngBytes.buffer.asUint8List());
- print("save file $file");
- return file.path;
- } catch (e) {
- print(e);
- }
- return null;
- }
- runShare(BuildContext context, int index, GlobalKey key, bool save, {bool app = false}) async {
- var path = await request(context, () async {
- return await _takePicture(index, key);
- });
- if (path == null) return;
- print("share path $path");
- if (save) {
- final result = await ImageGallerySaver.saveFile(path);
- if (result != null && result["isSuccess"] == true) ToastUtil.show("已保存至相册");
- } else {
- await showModalBottomSheet(
- context: context,
- backgroundColor: Colors.white,
- elevation: 10,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
- builder: (context) => MenuShareBottomContent(
- "Img",
- hasDownload: false,
- file: path,
- app: app,
- ),
- );
- }
- }
|