flutter生成二维码并截图保存到图库

news2024/11/27 16:37:01

在这里插入图片描述在这里插入图片描述

引入库:flutter_screenutil、image_gallery_saver、qr_flutter弹窗布局

import 'dart:async';
import 'dart:typed_data';
import 'package/generated/l10n.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/utils/ImageWaterMarkUtil.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package:jade/utils/Utils.dart';
import 'package:util/easy_loading_util.dart';
import 'package:util/navigator_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:qr_flutter/qr_flutter.dart';import 'dart:ui' as ui;
/*
* 普通说明弹窗(可隐藏取消按钮)
* */
Widget productQrcodeDialog (
    BuildContext context,
    { String descTitle,
      String subTitle,
      String desc,
      String qrStr,
      GlobalKey globalKey,
      Function callback,
      Function cancelCallback,
      bool showCancel = false,
      String sureBtnText,
      Color sureBtnTextColor
    }){
  return UnconstrainedBox(
      child: Container(
        alignment: Alignment.center,
        width: Utils().screenWidth(context)*0.8,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            if(descTitle != null)
              Container(
                  margin: EdgeInsets.only(top: 50.w),
                  child: Text(descTitle??'',style: TextStyle(color: JadeColors.grey_2,fontSize: 38.sp,fontWeight: FontWeight.w600))
              ),
            if(subTitle != null)
              Container(
                  margin: EdgeInsets.only(top: 20.w),
                  child: Text(subTitle,style: TextStyle(color: JadeColors.grey,fontSize: 24.sp))
              ),
            if(desc != null)
              Container(
                  margin: EdgeInsets.only(top: 30.w,bottom: 30.w),
                  padding: EdgeInsets.symmetric(horizontal: 30.w),
                  child: Text(desc,style: TextStyle(color: JadeColors.grey_2,fontSize: 30.sp),maxLines: 300,textAlign: TextAlign.center,)
              ),
            RepaintBoundary(
                key: globalKey,
                child: Container(
                    width: Utils().screenWidth(context)*0.6,
                    height: Utils().screenWidth(context)*0.6,
                    decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(10),
                        border: Border.all(width: 1,color: JadeColors.blue_2)
                    ),
                    child: Stack(
                      alignment: Alignment.center,
                      children: [
                        QrImage(
                          padding: EdgeInsets.all(11.w),
                          data: qrStr,
                          version: QrVersions.auto,
                          size: Utils().screenWidth(context) * 0.6,
                        ),
                        Container(
                          width: 60.w,
                          height: 60.w,
                          decoration: BoxDecoration(
                              color: Colors.white,
                              borderRadius: BorderRadius.circular(5),
                              border: Border.all(width: 1.w,color:Colors.white)
                          ),
                          child: Utils().roundedImage(PathConfig.httpAppLogo, 5),
                        )
                      ],
                    )
                ),
            ),
            Container(
              margin: EdgeInsets.only(top: 40.w),
              height: 0.5,color: JadeColors.grey_13,
            ),
            Container(
              height: 92.w,
              child: Row(
                children: [
                  if(showCancel)
                    Expanded(child: GestureDetector(
                      child: Container(
                          color: Colors.transparent,
                          alignment: Alignment.center,
                          child: Text(S.current.quxiao,style: TextStyle(color: JadeColors.grey,fontSize: 34.sp,fontWeight: FontWeight.w300))
                      ),
                      onTap: (){
                        NavigatorUtil.pop();
                        if(cancelCallback != null){
                          cancelCallback();
                        }
                      },
                    )),
                  if(showCancel)
                    Container(width: 0.5,color: JadeColors.grey_13,height: double.infinity,),
                  Expanded(child: GestureDetector(
                    child: Container(
                      alignment: Alignment.center,
                      color: Colors.transparent,
                      child: Text(sureBtnText??S.current.close,style: TextStyle(color: sureBtnTextColor??Colors.blue,fontSize: 34.sp,fontWeight: FontWeight.w600),textAlign: TextAlign.center),
                    ),
                    onTap: () async {
                      _saveScreenshot(globalKey);
                      if(callback != null){
                        callback();
                      }
                    },
                  )),
                ],
              ),
            )
          ],
        ),
      )
  );
}

  Future<Uint8List> takeScreenshot(GlobalKey _globalKey) async {
  try {
    RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject() as RenderRepaintBoundary;
    ui.Image image = await boundary.toImage(pixelRatio: 3.0); // 调整分辨率以适应高像素密度设备
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    if (byteData != null) {
      Uint8List pngBytes = byteData.buffer.asUint8List();
      return pngBytes;
    }
  } catch (e) {
    print(e);
  }
  return null;
}

 _saveScreenshot(GlobalKey globalKey) async {
  Uint8List screenshotBytes = await takeScreenshot(globalKey);
  if (screenshotBytes != null) {
    final result = await ImageGallerySaver.saveImage(screenshotBytes);
    print('result= $result');// 打印保存结果
    esLoadingToast('已保存截图至本地');
  }else{
    esLoadingToast('截图保存失败');
  }
  NavigatorUtil.pop();
}

弹窗

 /*
  * 产品二维码弹窗
  * */
  Future<void> productQrCodeDialog(BuildContext context,{String descTitle,String subTitle,String desc,String qrStr,GlobalKey globalKey,Function callback,Function cancelCallback,bool showCancel = false,String sureBtnText,Color sureBtnTextColor}) async {
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return productQrcodeDialog(context,descTitle: descTitle,subTitle: subTitle,desc: desc,qrStr: qrStr,globalKey: globalKey,showCancel: showCancel,sureBtnText: sureBtnText,sureBtnTextColor:sureBtnTextColor,callback: callback,cancelCallback : cancelCallback);
        });
  }

调用

GlobalKey _globalKey = new GlobalKey();
GestureDetector(
child:_btnView(),
onTap: (){
productQrCodeDialog(context,
   descTitle: '产品二维码',
   desc: '请保存下载该二维码并打印,随同产品一起寄送至站点。',
   qrStr: '二维码的内容',
   globalKey: _globalKey,
   showCancel: true,
   sureBtnText: '下载',
    sureBtnTextColor: JadeColors.grey_2,
    callback: (){}
  );
   }
}
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1558390.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三、强一致性介绍

这里写自定义目录标题 三、强一致性介绍3.1 基本理解3.2 DTP模型3.3 落地协议XA3.4 ⼆阶段提交模型3.5 ⼆阶段提交的问题3.6 navicat操作xa 三、强一致性介绍 3.1 基本理解 相关特点 强⼀致性解决⽅案要求在任何时间点&#xff0c;任何时刻查询&#xff0c;参与全局事务的各个…

ROS 2边学边练(7)-- 何为动作(actions)

概念 我们先来看一张动图&#xff0c;下文再围绕这张图对动作作简单阐释和说明。 如上图所示&#xff0c;动作的复杂度比之前提到的几种通信方式&#xff08;主题、服务&#xff09;要大一点&#xff0c;但是几者之间也有着千丝万缕的关系&#xff0c;动作糅合了主题和服务的机…

【MySQL】DQL-排序查询-语法&排序方式&注意事项&可cv例题语句

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

常用技术-Stream流

目录 Stream流是什么&#xff1f; 认识Stream流 流和集合的区别 Stream流的操作 中间操作 Filter(过滤) Map(转换) Sorted(排序) Distinct(去重) Limit(限制) Skip(跳过) Peek(展示) 终止操作 forEach(循环) Collect(收集) Count(计数) Reduce(聚合) 使用Strea…

我爱DFS序列搜索

什么是DFS&#xff1f; DFS算法&#xff0c;即深度优先搜索&#xff08;Depth-First Search&#xff09;算法&#xff0c;是一种用于遍历或搜索图或树的算法。DFS算法可以解决诸如路径查找、图的连通性、拓扑排序以及树结构中的深度遍历等问题。然而&#xff0c;需要注意的是&…

C++基础12:标准模板库

此专栏为移动机器人知识体系下的编程语言中的 C {\rm C} C从入门到深入的专栏&#xff0c;参考书籍&#xff1a;《深入浅出 C {\rm C} C》(马晓锐)和《从 C {\rm C} C到 C {\rm C} C精通面向对象编程》(曾凡锋等)。 11.标准模板库 11.1 泛型化编程与STL简介 泛型化编程思想是一…

实践笔记-harbor搭建(版本:2.9.0)

harbor搭建 1.下载安装包&#xff08;版本&#xff1a;2.9.0&#xff09;2.修改配置文件3.安装4.访问harbor5.可能用得上的命令: 环境&#xff1a;centos7 1.下载安装包&#xff08;版本&#xff1a;2.9.0&#xff09; 网盘资源&#xff1a;https://pan.baidu.com/s/1fcoJIa4x…

垃圾回收机制--GC 垃圾收集器--JVM调优-面试题

1.触发垃圾回收的条件 新生代 Eden区域满了&#xff0c;触发young gc (ygc)老年代区域满了&#xff0c;触发full gc (fgc)通过ygc后进入老年代的平均大小大于老年代的可用内存,触发full gc(fgc).程序中主动调用的System.gc()强制执行gc,是full gc&#xff0c;但是不必然执行。…

KUKA机器人调整示教器灵敏度(校屏)

KUKA机器人KRC4的示教器升级后&#xff0c;示教器屏幕由之前的电阻屏改为电容屏&#xff0c;不仅在外观上有所变化&#xff0c;屏幕校准的方法也有所不同。通过以下方法分别对新旧两款示教器进行屏幕校正&#xff0c;调整示教器屏幕灵敏度。 对新款示教器而言&#xff1a; 一…

热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜

热烈祝贺阿里云PolarDB登顶2024最新一期中国数据库流行榜 墨天轮墨天轮国产数据库流行度排行PolarDB首度夺魁关于话题的讨论数据库流行度排行榜会影响你的数据库选型吗&#xff1f;对于 PolarDB 的本次登顶&#xff0c;你认为关键因素是什么&#xff1f;PolarDB“三层分离”新版…

LeetCode-331. 验证二叉树的前序序列化【栈 树 字符串 二叉树】

LeetCode-331. 验证二叉树的前序序列化【栈 树 字符串 二叉树】 题目描述&#xff1a;解题思路一&#xff1a;看提示主要是栈和树。这题其实不是二叉树的遍历题&#xff0c;而是检验二叉树基础知识的题&#xff0c;也许有些难想。第一种解法是&#xff1a;把有效的叶子节点使用…

【OceanBase实战之路】第3篇:多租户架构实现资源隔离

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 一、什么是OceanBase的多租户二、兼容模式2.1 MySQL 模式2.2 Oracle 模式三、租户介绍3.1 系统租户3.2 用户租户3.3 Meta 租…

强化基础-Java-泛型基础

什么是泛型&#xff1f; 泛型其实就参数化类型&#xff0c;也就是说这个类型类似一个变量是可变的。 为什么会有泛型&#xff1f; 在没有泛型之前&#xff0c;java中是通过Object来实现泛型的功能。但是这样做有下面两个缺陷&#xff1a; 1 获取值的时候必须进行强转 2 没有…

计算机网络-TCP/IP 网络模型

TCP/IP网络模型各层的详细描述&#xff1a; 应用层&#xff1a;应用层为应用程序提供数据传输的服务&#xff0c;负责各种不同应用之间的协议。主要协议包括&#xff1a; HTTP&#xff1a;超文本传输协议&#xff0c;用于从web服务器传输超文本到本地浏览器的传送协议。FTP&…

Linux 设备树: 设备树节点与属性在 dtb 文件中的存储

前言 当前新版本的 Linux 内核 设备驱动框架&#xff0c;与设备树&#xff08;Device Tree&#xff09;结合密切&#xff0c;整体 设备树的设备驱动框架&#xff0c;比较的庞大&#xff0c;但又非常的经典。 一个个的 设备树解析函数&#xff0c;都是前人【智慧】的结晶&#…

微服务监控:确保分布式系统的可观察性与稳定性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 一、前言二、微服务监控的重要性三、关键监控指标四、常用监控工具五、最佳实践六、结论 一、前言 在当前的软件开发领域&a…

2.快速排序

快速排序 思想&#xff1a;双指针法&#xff08;左右指针法&#xff09; 时间复杂度&#xff1a;O(n log n)&#xff08;最理想的情况下&#xff09; 最坏的情况&#xff1a;输入的数组已经是有序的或者接近有序时 快速排序的性能会退化到O(n^2) 我们的快速排序其实就是让两…

Wezterm配置

Windows 的图形界面目前来说在有图形界面的系统中&#xff0c;表现最稳定 linux 的终端最方便 和 tui 程序也多 我建议winodws安装 wsl 既可以使用 linux的环境和可以使用windows的桌面 关键 neovide --wsl 的表现很棒 如果项目的历史提交很多而且&#xff0c;工程很大&#xf…

C++STLmap,set

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

吴恩达2022机器学习专项课程(一) 4.4 学习率

问题预览/关键词 学习率太小有什么影响&#xff1f;学习率太大有什么影响&#xff1f;如果成本函数达到局部最小值&#xff0c;使用梯度下降还能继续最小化吗&#xff1f;为什么学习率固定&#xff0c;而最小化成本函数的步幅却越来越缓&#xff1f;如何选择合适的学习率&…