flutter如何实现电子签名

在Flutter中如何实现电子签名功能?需要让用户直接在屏幕上手写签名,并能保存为图片或其他格式。目前尝试了CustomPainter,但遇到笔画不连贯和性能问题。有没有成熟的插件或最佳实践方案?希望支持撤销、清空、调整笔触粗细等功能,最好能兼容iOS和Android平台。

2 回复

使用Flutter实现电子签名,可通过CustomPainter绘制画布,监听触摸事件记录轨迹。常用第三方库如signature简化开发,支持保存为图片。

更多关于flutter如何实现电子签名的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现电子签名可以通过以下步骤完成:

1. 使用 CustomPaintGestureDetector

创建一个自定义画布,通过手势监听记录用户绘制路径。

2. 核心代码示例

import 'package:flutter/material.dart';

class SignaturePad extends StatefulWidget {
  @override
  _SignaturePadState createState() => _SignaturePadState();
}

class _SignaturePadState extends State<SignaturePad> {
  List<Offset> points = [];

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox renderBox = context.findRenderObject() as RenderBox;
          points.add(renderBox.globalToLocal(details.globalPosition));
        });
      },
      onPanEnd: (DragEndDetails details) {
        points.add(Offset.zero); // 标记路径结束
      },
      child: CustomPaint(
        painter: SignaturePainter(points),
        size: Size.infinite,
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  final List<Offset> points;

  SignaturePainter(this.points);

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 4.0;

    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != Offset.zero && points[i + 1] != Offset.zero) {
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(SignaturePainter oldDelegate) => oldDelegate.points != points;
}

3. 保存签名

使用 RepaintBoundaryGlobalKey 将画布转换为图片:

final GlobalKey globalKey = GlobalKey();

// 转换为图片
Future<Uint8List> captureSignature() async {
  try {
    RenderRepaintBoundary boundary = globalKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage();
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    return byteData.buffer.asUint8List();
  } catch (e) {
    return null;
  }
}

4. 清除功能

void clearSignature() {
  setState(() {
    points.clear();
  });
}

5. 完整使用

Scaffold(
  body: Column(
    children: [
      RepaintBoundary(
        key: globalKey,
        child: Container(
          color: Colors.white,
          child: SignaturePad(),
        ),
      ),
      Row(
        children: [
          ElevatedButton(
            onPressed: captureSignature,
            child: Text('保存'),
          ),
          ElevatedButton(
            onPressed: clearSignature,
            child: Text('清除'),
          ),
        ],
      )
    ],
  ),
);

注意事项:

  • 可通过调整 strokeWidth 改变线条粗细
  • 使用 StrokeCap.round 使线条端点更圆润
  • 建议设置画布固定尺寸避免溢出
  • 实际项目中可添加撤销、重做等功能

这是最基础的实现方案,如需更复杂功能可考虑使用 signature 第三方包。

回到顶部