Flutter使用pretty_qr_code生成高颜值二维码

1 阅读6分钟

前言

最近在项目里需要实现自定义样式、带Logo、渐变色的高颜值二维码功能,对比多款插件后,pretty_qr_code凭借丰富的定制能力、简洁API和多平台适配性脱颖而出。 本文基于pretty_qr_code: ^3.6.0版本编写,适配Flutter 3.0+,支持iOS、Android、Windows、Web全平台,可满足基础生成、样式定制、Logo嵌入、图片导出等全场景需求。

官方文档:传送门

pretty-qr-code.png

1. 插件核心API

pretty_qr_code的核心由主组件装饰配置类组成,参数清晰易扩展,是实现定制化二维码的核心。

1.1 核心组件:PrettyQrView

负责渲染二维码的主组件,支持直接传入数据快速生成。

属性类型必填说明
dataString二维码承载的内容(链接/文本/数字等)
sizedouble二维码尺寸,默认自适应父容器
decorationPrettyQrDecoration二维码样式装饰(形状/颜色/Logo)
errorCorrectionLevelQrErrorCorrectLevel纠错级别,默认high(30%容错)
backgroundColorColor二维码背景色,默认白色
clipBehaviorClip裁剪模式,默认Clip.hardEdge

1.2 核心配置类:PrettyQrDecoration

二维码样式定制核心,控制形状、颜色、Logo、边距等。

属性类型说明
shapePrettyQrShape码点形状(方形/圆形/圆角/水滴等)
colorColor二维码纯色(与渐变二选一)
gradientGradient二维码渐变色(与纯色二选一)
imagePrettyQrDecorationImage中间嵌入的Logo配置
quietZonePrettyQrQuietZone二维码边距(空白区域)

1.3 常用枚举/子类

  • PrettyQrShapesquare(方形)、circle(圆形)、rounded(圆角)、fluid(水滴)、diamond(菱形)
  • QrErrorCorrectLevellow(7%)、medium(15%)、quartile(25%)、high(30%)
  • PrettyQrDecorationImage:配置Logo图片、尺寸、边距

2. 基础使用

2.1 引入依赖

pubspec.yaml中添加最新版依赖:

dependencies:
  flutter:
    sdk: flutter
  pretty_qr_code: ^3.6.0

执行flutter pub get安装依赖。

2.2 最简二维码生成

无需任何定制,一行代码生成标准二维码:

import 'package:flutter/material.dart';
import 'package:pretty_qr_code/pretty_qr_code.dart';

// 最简二维码
PrettyQrView.data(
  data: 'https://flutter.dev', // 二维码内容
  size: 200, // 尺寸
)

2.3 带基础样式的二维码

快速配置形状与颜色,提升美观度:

PrettyQrView.data(
  data: 'https://flutter.dev',
  size: 200,
  decoration: const PrettyQrDecoration(
    // 圆形码点
    shape: PrettyQrShape.circle(),
    // 二维码颜色
    color: Color(0xFF6200EE),
    // 边距
    quietZone: PrettyQrQuietZone.standard,
  ),
)

3. 高级功能定制

3.1 自定义码点形状

支持多种预设形状,轻松切换风格:

// 圆角码点
PrettyQrShape.rounded(radius: 8)
// 水滴形状
PrettyQrShape.fluid()
// 菱形码点
PrettyQrShape.diamond()

3.2 渐变色二维码

告别单色,支持线性/径向渐变:

PrettyQrView.data(
  data: 'https://flutter.dev',
  size: 200,
  decoration: PrettyQrDecoration(
    shape: const PrettyQrShape.rounded(),
    // 线性渐变
    gradient: const LinearGradient(
      colors: [Color(0xFF6200EE), Color(0xFF03DAC6)],
      begin: Alignment.topLeft,
      end: Alignment.bottomRight,
    ),
  ),
)

3.3 嵌入中间Logo

支持本地资源/网络图片Logo,自带容错保护:

PrettyQrView.data(
  data: 'https://flutter.dev',
  size: 220,
  decoration: const PrettyQrDecoration(
    shape: PrettyQrShape.circle(),
    color: Color(0xFF6200EE),
    // 嵌入Logo
    image: PrettyQrDecorationImage(
      image: AssetImage('assets/images/logo.png'), // 本地图片
      // image: NetworkImage('https://xxx.com/logo.png'), // 网络图片
      size: 40, // Logo尺寸
      padding: EdgeInsets.all(4), // Logo内边距
    ),
  ),
)

3.4 自定义纠错级别

根据场景调整容错率,Logo较大时建议用最高级别:

PrettyQrView.data(
  data: 'https://flutter.dev',
  // 最高纠错级别(30%容错,适合带大Logo)
  errorCorrectionLevel: QrErrorCorrectLevel.high,
)

3.5 自定义背景与边框

PrettyQrView.data(
  data: 'https://flutter.dev',
  size: 200,
  backgroundColor: const Color(0xFFF5F5F5), // 背景色
  decoration: const PrettyQrDecoration(
    shape: PrettyQrShape.square(),
    color: Color(0xFF2196F3),
  ),
)

4. 二维码导出与保存

pretty_qr_code仅负责渲染,导出图片需结合flutter_screenutilscreenshotgal插件实现截图→保存相册,适配全平台。

4.1 新增依赖

dependencies:
  pretty_qr_code: ^3.6.0
  screenshot: ^3.0.0
  gal: ^2.3.2
  permission_handler: ^11.3.1

4.2 权限配置

  • AndroidAndroidManifest.xml):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
  • iOSInfo.plist):
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问相册以保存二维码图片</string>

4.3 导出保存代码实现

import 'package:flutter/material.dart';
import 'package:pretty_qr_code/pretty_qr_code.dart';
import 'package:screenshot/screenshot.dart';
import 'package:gal/gal.dart';
import 'package:permission_handler/permission_handler.dart';

class QrCodeExportPage extends StatefulWidget {
  const QrCodeExportPage({super.key});

  @override
  State<QrCodeExportPage> createState() => _QrCodeExportPageState();
}

class _QrCodeExportPageState extends State<QrCodeExportPage> {
  final ScreenshotController _screenshotController = ScreenshotController();

  // 保存二维码到相册
  Future<void> _saveQrCodeToGallery() async {
    // 申请权限
    final status = await Permission.storage.request();
    if (!status.isGranted) {
      debugPrint('权限申请失败');
      return;
    }

    // 截图
    final imageBytes = await _screenshotController.capture(
      pixelRatio: 2.0, // 高清导出
      delay: const Duration(milliseconds: 20),
    );

    if (imageBytes == null) {
      debugPrint('截图失败');
      return;
    }

    // 保存到相册
    await Gal.putImageBytes(imageBytes, album: 'Flutter二维码');
    debugPrint('保存成功');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('二维码导出')),
      body: Center(
        child: Screenshot(
          controller: _screenshotController,
          child: PrettyQrView.data(
            data: 'https://flutter.dev',
            size: 200,
            decoration: const PrettyQrDecoration(
              shape: PrettyQrShape.circle(),
              color: Color(0xFF6200EE),
              image: PrettyQrDecorationImage(
                image: AssetImage('assets/images/logo.png'),
                size: 40,
              ),
            ),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _saveQrCodeToGallery,
        child: const Icon(Icons.save),
      ),
    );
  }
}

5. 注意事项

  1. Logo大小限制:Logo尺寸建议不超过二维码整体的20%,避免扫码失败;纠错级别建议使用high
  2. 图片模糊问题:导出时将pixelRatio设为1.5~3.0,可提升清晰度,兼顾体积与画质。
  3. Platform View不兼容:二维码内嵌套WebView、地图等原生组件会渲染异常,仅支持Flutter纯组件。
  4. 数据长度限制:内容越长二维码越复杂,建议短链接/精简文本,过长会降低扫码成功率。
  5. Web平台适配:导出图片需通过浏览器API处理,captureAndSave不支持Web端。
  6. 性能优化:页面内大量渲染二维码时,建议固定尺寸并缓存组件,避免重复重建。

6. 总结

pretty_qr_code 3.6.0是Flutter生态中定制能力最强、使用最简单的二维码生成插件,完美覆盖:

  • 基础二维码快速生成
  • 形状/颜色/渐变全样式定制
  • 中间Logo嵌入
  • 高清导出与相册保存

配合截图与权限插件,可快速实现商业级二维码功能,适配全平台、易扩展、易维护,是开发中生成高颜值二维码的首选方案。

本文仅是基础案例,实际项目可结合主题、动画、交互实现更丰富的二维码效果,欢迎在评论区交流探讨~


本次分享就到这儿啦,我是鹏多多,深耕前端的技术创作者,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

PS:在本页按F12,在console中输入document.getElementsByClassName('panel-btn')[0].click();有惊喜哦~

往期文章