Want to create Signature in flutter? Signature Class need to be modified to respond to VerticalDrag , I renamed it to Signature1
now signature area pad should not scroll , you can check the complete code below as it behaves. you will find out that Signature area is no more scrolling with the SingleChildScrollView.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | 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; } } |
If you like this question & answer and want to contribute, then write your question & answer and email to freewebmentor[@]gmail.com. Your question and answer will appear on FreeWebMentor.com and help other developers.