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
``` 截圖功能參考文章