Flutter中实现签名功能
我们可以使用GestureDetector
记录触摸,使用CustomPaint
在屏幕上绘制线条从而实现签名功能
参考步骤
- 使用
RenderBox.globalToLocal
将GestureDetector.onPanUpdate
提供的DragUpdateDetails
转换为相对坐标 - 使用
GestureDetector.onPanEnd
手势处理程序记录笔画之间的中断。 - Mutating the same
List
won't automatically trigger a repaint because theCustomPainter
constructor arguments are the same. You can trigger a repaint by creating a newList
each time a new point is provided. - 改变相同的
List
不会自动触发重绘,因为CustomPainter
构造函数参数是相同的。每次提供新点时,您都可以通过创建一个新的“列表”来触发重绘。 - 使用
Canvas.drawLine
在签名的每个记录点之间画一条线。
参考代码
```Dart
import 'package:flutter/material.dart';
class SignaturePainter extends CustomPainter { SignaturePainter(this.points);
final List
void paint(Canvas canvas, Size size) { Paint paint = new Paint() ..color = Colors.black ..strokeCap = StrokeCap.round ..strokeWidth = 5.0; for (int i = 0; i < points.length - 1; i++) { if (points[i] != null && points[i + 1] != null) canvas.drawLine(points[i], points[i + 1], paint); } }
bool shouldRepaint(SignaturePainter other) => other.points != points; }
class Signature extends StatefulWidget { SignatureState createState() => new SignatureState(); }
class SignatureState extends State
Widget build(BuildContext context) { return new Stack( children: [ GestureDetector( onPanUpdate: (DragUpdateDetails details) { RenderBox referenceBox = context.findRenderObject(); Offset localPosition = referenceBox.globalToLocal(details.globalPosition);
setState(() {
_points = new List.from(_points)..add(localPosition);
});
},
onPanEnd: (DragEndDetails details) => _points.add(null),
),
CustomPaint(painter: SignaturePainter(_points), size: Size.infinite),
],
);
} }
class DemoApp extends StatelessWidget { Widget build(BuildContext context) => new Scaffold(body: new Signature()); }
void main() => runApp(new MaterialApp(home: new DemoApp())); ``` 签名参考文章
截图保存签名图层
使用RepaintBoundary 在State中实现如下代码
```dart
class _MyHomePageState extends State
@override Widget build(BuildContext context) { return RepaintBoundary( key: rootWidgetKey, child: Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Column( ..... ), ), ); } }
``` 通过rootWidgetKey可以拿到RenderRepaintBoundary的引用,进来拿到内部组件的截图:
```dart
class _MyHomePageState extends State
Future
``` 截图功能参考文章