我在flutter项目中实现了signature_pad,它工作正常。
不幸的是,当我将其放置在内部时SingleChildScrollView,并未画出签名。它滚动而不是签名。
SingleChildScrollView
似乎是,GestureDetector但我不知道如何解决。
GestureDetector
有人可以给我一些线索吗?
谢谢。
Signature Class需要修改以响应VerticalDrag,我将其重命名为Signature1
Signature Class
VerticalDrag
Signature1
现在签名区域键盘不应该滚动,您可以按照其行为检查下面的完整代码。您会发现Signature区域不再用滚动SingleChildScrollView。
import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'dart:async'; import 'dart:ui' as ui; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { var color = Colors.black; var strokeWidth = 3.0; final _sign = GlobalKey<Signature1State>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: SingleChildScrollView( child: Column( children: <Widget>[ _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), SizedBox(height: 15), _showCategory(), _showSignaturePad() ], ), ) , ); } Widget _showCategory() { return TextField( onTap: () { FocusScope.of(context).requestFocus(FocusNode()); }, style: TextStyle(fontSize: 12.0, height: 1.0), decoration: InputDecoration(hintText: "TextView")); } Widget _showSignaturePad() { return Container( width: double.infinity, height: 200, child: Padding( padding: const EdgeInsets.all(8.0), child: Container( height: 200, //color: Colors.red, child: Signature1( color: color, key: _sign, strokeWidth: strokeWidth, ), ), ), color: Colors.grey.shade300, ); } } class Signature1 extends StatefulWidget { final Color color; final double strokeWidth; final CustomPainter backgroundPainter; final Function onSign; Signature1({ this.color = Colors.black, this.strokeWidth = 5.0, this.backgroundPainter, this.onSign, Key key, }) : super(key: key); Signature1State createState() => Signature1State(); static Signature1State of(BuildContext context) { return context.findAncestorStateOfType<Signature1State>(); } } class _SignaturePainter extends CustomPainter { Size _lastSize; final double strokeWidth; final List<Offset> points; final Color strokeColor; Paint _linePaint; _SignaturePainter({@required this.points, @required this.strokeColor, @required this.strokeWidth}) { _linePaint = Paint() ..color = strokeColor ..strokeWidth = strokeWidth ..strokeCap = StrokeCap.round; } @override void paint(Canvas canvas, Size size) { _lastSize = size; for (int i = 0; i < points.length - 1; i++) { if (points[i] != null && points[i + 1] != null) canvas.drawLine(points[i], points[i + 1], _linePaint); } } @override bool shouldRepaint(_SignaturePainter other) => other.points != points; } class Signature1State extends State<Signature1> { List<Offset> _points = <Offset>[]; _SignaturePainter _painter; Size _lastSize; Signature1State(); void _onDragStart(DragStartDetails details){ RenderBox referenceBox = context.findRenderObject(); Offset localPostion = referenceBox.globalToLocal(details.globalPosition); setState(() { _points = List.from(_points) ..add(localPostion) ..add(localPostion); }); } void _onDragUpdate (DragUpdateDetails details) { RenderBox referenceBox = context.findRenderObject(); Offset localPosition = referenceBox.globalToLocal(details.globalPosition); setState(() { _points = List.from(_points)..add(localPosition); if (widget.onSign != null) { widget.onSign(); } }); } void _onDragEnd (DragEndDetails details) => _points.add(null); @override Widget build(BuildContext context) { WidgetsBinding.instance.addPostFrameCallback((_) => afterFirstLayout(context)); _painter = _SignaturePainter(points: _points, strokeColor: widget.color, strokeWidth: widget.strokeWidth); return ClipRect( child: CustomPaint( painter: widget.backgroundPainter, foregroundPainter: _painter, child: GestureDetector( onVerticalDragStart: _onDragStart, onVerticalDragUpdate: _onDragUpdate, onVerticalDragEnd: _onDragEnd, onPanStart: _onDragStart, onPanUpdate: _onDragUpdate, onPanEnd: _onDragEnd ), ), ); } Future<ui.Image> getData() { var recorder = ui.PictureRecorder(); var origin = Offset(0.0, 0.0); var paintBounds = Rect.fromPoints(_lastSize.topLeft(origin), _lastSize.bottomRight(origin)); var canvas = Canvas(recorder, paintBounds); if(widget.backgroundPainter != null) { widget.backgroundPainter.paint(canvas, _lastSize); } _painter.paint(canvas, _lastSize); var picture = recorder.endRecording(); return picture.toImage(_lastSize.width.round(), _lastSize.height.round()); } void clear() { setState(() { _points = []; }); } bool get hasPoints => _points.length > 0; List<Offset> get points => _points; afterFirstLayout(BuildContext context) { _lastSize = context.size; } }