二维码生成是工具箱中的重要功能。用户可以快速生成各种内容的二维码,包括文本、URL和联系信息。本文将详细讲解如何实现二维码生成工具。

二维码生成工具的应用

二维码在现代应用中有广泛的应用。用户可以使用二维码来分享信息、进行支付、访问网站等。

在工具页面中,二维码生成工具已经定义在工具列表中:

{'icon': Icons.qr_code_2, 'title': '二维码生成'},

说明:这里把二维码入口放在工具列表里,和其他功能保持一致的展示方式。Icons.qr_code_2 是系统自带图标,title 用于列表标题与后续路由判断,避免硬编码散落在页面中。

二维码生成对话框的实现

当用户点击二维码生成工具时,会显示一个对话框。这个对话框提供了输入和输出的界面:

void _showToolDetail(BuildContext context, String title) {
  showDialog(
    context: context,
    builder: (_) => _QrGenerateDialog(title: title),
  );
}

说明:入口方法只负责弹窗,不在这里堆逻辑。把实现放进单独的对话框组件里,后面要加“保存 / 分享 / 校验”都更顺手,也更像真实项目的写法。

class _QrGenerateDialog extends StatefulWidget {
  const _QrGenerateDialog({required this.title});
  final String title;

  
  State<_QrGenerateDialog> createState() => _QrGenerateDialogState();
}

说明:用 StatefulWidget 是因为二维码内容会跟着输入变化。这里把 title 作为参数传进来,保持工具弹窗的通用性(同一个对话框结构,换个标题就能复用)。

class _QrGenerateDialogState extends State<_QrGenerateDialog> {
  final _inputController = TextEditingController();
  String _data = '';

  
  void dispose() {
    _inputController.dispose();
    super.dispose();
  }
}

说明:输入用 TextEditingController 管起来,后面做“一键清空”“复制内容”会方便很多。dispose() 里记得释放,避免弹窗多次打开后出现资源泄露(这个坑挺常见)。


Widget build(BuildContext context) {
  return AlertDialog(
    title: Text(widget.title),
    content: TextField(
      controller: _inputController,
      maxLines: 4,
      onChanged: (v) => setState(() => _data = v.trim()),
      decoration: const InputDecoration(hintText: '输入内容'),
    ),
  );
}

说明:这里不再做“输出结果 TextField”,因为二维码本身就是结果,直接渲染更直观。trim() 的小处理能减少用户复制粘贴时带来的首尾空格问题。

二维码的编码实现

二维码的编码需要使用专门的库。在Flutter中,我们可以使用qr_flutter包来生成二维码。

dependencies:
  qr_flutter: ^4.1.0

说明:依赖一般直接加在 pubspec.yamldependencies 里。版本号你可以按工程实际情况锁定,不建议一路用 any,排查问题的时候会省事一些。

import 'package:qr_flutter/qr_flutter.dart';

QrImage(
  data: _data,
  version: QrVersions.auto,
  size: 200.0,
)

说明QrImage 是最直接的渲染组件,data 是要编码的数据内容。QrVersions.auto 可以自动适配长度,避免小内容却强制大尺寸版本。size 控制二维码在对话框中的视觉尺寸,建议跟 UI 规范保持一致。

补充一点:如果输入内容过长,建议在生成前做长度提示,避免二维码过密影响识别率。

二维码的预览

生成的二维码可以在对话框中预览。用户可以看到生成的二维码,并确认内容是否正确。

说明:实际产品里,我会在预览区域旁边加一个小提示(例如“点击二维码可放大”),降低用户学习成本。这个提示不需要写成复杂的组件,用一行 Text 就够了。

content: SingleChildScrollView(
  child: Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      TextField(
        controller: _inputController,
        maxLines: 4,
        onChanged: (v) => setState(() => _data = v.trim()),
        decoration: const InputDecoration(hintText: '输入内容'),
      ),
      if (_data.isNotEmpty) ...[
        const SizedBox(height: 12),
        QrImage(data: _data, version: QrVersions.auto, size: 180),
      ],
    ],
  ),
),

说明:这里用 if (_data.isNotEmpty) 做了个小判断,输入为空就不渲染二维码,界面不会显得“默认一块黑”。另外 SingleChildScrollView 是为了防止小屏弹窗内容被挤压。

二维码的保存和分享

生成的二维码可以保存到本地文件系统,或者分享给其他应用。这需要使用文件系统API和分享API来实现。

void _saveQRCode() async {
  try {
    final directory = await getApplicationDocumentsDirectory();
    final file = File('${directory.path}/qrcode_${DateTime.now().millisecondsSinceEpoch}.png');
    // 保存二维码到文件
  } catch (e) {
    // 处理错误
  }
}

说明:这里先拿应用目录,再以时间戳生成文件名,避免覆盖之前的二维码。真实项目中我会把“保存成功/失败”的结果通过 SnackBar 提示给用户,让操作反馈更明确。

actions: [
  TextButton(
    onPressed: () => Navigator.pop(context),
    child: const Text('关闭'),
  ),
  TextButton(
    onPressed: _data.isEmpty ? null : _saveQRCode,
    child: const Text('保存'),
  ),
],

说明:按钮是否可用直接跟 _data 绑定,用户一眼就知道“现在还不能保存”。这种小交互做完,弹窗用起来会顺很多。

二维码内容的验证

在生成二维码之前,我们应该验证输入的内容。例如,如果输入的是URL,我们应该检查它是否是有效的URL。

补充说明:简单校验可以用 Uri.tryParse,再判断 hasAbsolutePathhasScheme。不建议把校验逻辑写死在 UI 层,放在工具类里更方便复用。

final uri = Uri.tryParse(_data);
final looksLikeUrl = uri != null && uri.hasScheme && uri.host.isNotEmpty;

说明:我一般不做“严格到过分”的校验,避免用户输入一些内部链接/测试环境地址被误判。这里的判断属于“够用”的那种:有 scheme 且有 host,基本就能当成 URL 来处理。

二维码的大小和纠错级别

二维码的大小和纠错级别会影响二维码的可读性。纠错级别越高,二维码的容错能力越强,但二维码的大小也会增加。

补充说明:如果二维码用于海报或打印,建议提高纠错级别;如果只是手机内展示,普通等级即可。不同场景取舍不一样,别一刀切。

总结

二维码生成工具展示了如何在Flutter应用中实现二维码生成功能。通过使用qr_flutter包,我们可以快速生成各种内容的二维码。这个工具可以用于信息分享、支付、网站访问等多个领域。

收尾补充:实际开发时,可以把二维码生成做成独立组件,后续其它模块(名片分享、活动报名)都能复用,维护成本会更低。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐