1
+ import 'package:flutter/material.dart' ;
2
+
3
+
4
+ class GestureDemo extends StatefulWidget {
5
+ @override
6
+ _GestureDemoState createState () => _GestureDemoState ();
7
+ }
8
+
9
+ class _GestureDemoState extends State <GestureDemo > {
10
+ Offset _startingFocalPoint;
11
+ Offset _previousOffset;
12
+ Offset _offset = Offset .zero;
13
+
14
+ double _previousZoom;
15
+ double _zoom = 1.0 ;
16
+
17
+ static const List <MaterialColor > kSwatches = < MaterialColor > [
18
+ Colors .red,
19
+ Colors .pink,
20
+ Colors .purple,
21
+ Colors .deepPurple,
22
+ Colors .indigo,
23
+ Colors .blue,
24
+ Colors .lightBlue,
25
+ Colors .cyan,
26
+ Colors .green,
27
+ Colors .lime,
28
+ Colors .yellow,
29
+ Colors .amber,
30
+ Colors .orange,
31
+ Colors .deepOrange,
32
+ Colors .brown,
33
+ Colors .grey,
34
+ Colors .blueGrey,
35
+ ];
36
+
37
+ int _swatchIndex = 0 ;
38
+ MaterialColor _swatch = kSwatches.first;
39
+ MaterialColor get swatch => _swatch;
40
+
41
+ bool _forward = true ;
42
+ bool _scaleEnabled = true ;
43
+ bool _tapEnabled = true ;
44
+ bool _doubleTapEnabled = true ;
45
+ bool _longPressEnabled = true ;
46
+
47
+ void _handleScaleStart (ScaleStartDetails details){
48
+ setState (() {
49
+ _startingFocalPoint = details.focalPoint;
50
+ _previousOffset = _offset;
51
+ _previousZoom = _zoom;
52
+ });
53
+ }
54
+ void _handleScaleUpdate (ScaleUpdateDetails details){
55
+ setState (() {
56
+ _zoom = _previousZoom * details.scale;
57
+
58
+ final Offset normalizedOffset = (_startingFocalPoint - _previousOffset) / _previousZoom;
59
+ _offset = details.focalPoint - normalizedOffset * _zoom;
60
+ });
61
+ }
62
+
63
+ void _handleScaleReset (){
64
+ setState (() {
65
+ _zoom = 1.0 ;
66
+ _offset = Offset .zero;
67
+ });
68
+ }
69
+
70
+ void _handleColorChange (){
71
+ setState (() {
72
+ _swatchIndex+= 1 ;
73
+ if (_swatchIndex == kSwatches.length){
74
+ _swatchIndex = 0 ;
75
+ }
76
+ _swatch = kSwatches[_swatchIndex];
77
+ });
78
+ }
79
+
80
+ void _handleDirectionChange (){
81
+ setState (() {
82
+ _forward = ! _forward;
83
+ });
84
+ }
85
+
86
+ @override
87
+ Widget build (BuildContext context) {
88
+ return new Scaffold (
89
+ appBar: new AppBar (
90
+ title: const Text ('Gestures Demo' ),
91
+ ),
92
+ body: Stack (
93
+ fit: StackFit .expand,
94
+ children: < Widget > [
95
+ GestureDetector (
96
+ onScaleStart: _scaleEnabled ? _handleScaleStart: null ,
97
+ onScaleUpdate: _scaleEnabled ? _handleScaleUpdate: null ,
98
+ onTap: _tapEnabled? _handleColorChange: null ,
99
+ onDoubleTap: _doubleTapEnabled? _handleScaleReset: null ,
100
+ onLongPress: _longPressEnabled? _handleDirectionChange: null ,
101
+ child: CustomPaint (
102
+ painter: _GesturePainter (
103
+ zoom: _zoom,
104
+ offset: _offset,
105
+ swatch: swatch,
106
+ forward: _forward,
107
+ scaleEnabled: _scaleEnabled,
108
+ tapEnabled: _tapEnabled,
109
+ doubleTapEnabled: _doubleTapEnabled,
110
+ longPressEnabled: _longPressEnabled,
111
+ ),
112
+ ),
113
+ ),
114
+ Positioned (
115
+ bottom: 0.0 ,
116
+ left: 0.0 ,
117
+ child: Card (
118
+ child: Container (
119
+ padding: const EdgeInsets .all (4.0 ),
120
+ child: Column (
121
+ children: < Widget > [
122
+ Row (
123
+ children: < Widget > [
124
+ Checkbox (
125
+ value: _scaleEnabled,
126
+ onChanged: (bool value){
127
+ setState (() {
128
+ _scaleEnabled = value;
129
+ });
130
+ }
131
+ ),
132
+ const Text ('Scale' ),
133
+ ],
134
+ ),
135
+ Row (
136
+ children: < Widget > [
137
+ Checkbox (
138
+ value: _tapEnabled,
139
+ onChanged: (bool value){
140
+ setState (() {
141
+ _tapEnabled = value;
142
+ });
143
+ },
144
+ ),
145
+ const Text ('Tap-【change Color】' )
146
+ ],
147
+ ),
148
+ Row (
149
+ children: < Widget > [
150
+ Checkbox (
151
+ value: _doubleTapEnabled,
152
+ onChanged: (bool value){
153
+ setState (() {
154
+ _doubleTapEnabled = value;
155
+ });
156
+ },
157
+ ),
158
+ const Text ('d-Tap【Reset】' ),
159
+ ],
160
+ ),
161
+ Row (
162
+ children: < Widget > [
163
+ Checkbox (
164
+ value: _longPressEnabled,
165
+ onChanged: (bool value){
166
+ setState (() {
167
+ _longPressEnabled = value;
168
+ });
169
+ },
170
+ ),
171
+ const Text ('Long Press【direction Change】' ),
172
+ ],
173
+ )
174
+ ],
175
+ crossAxisAlignment: CrossAxisAlignment .start,
176
+ ),
177
+ ),
178
+ ),
179
+ )
180
+ ],
181
+ ),
182
+ );
183
+ }
184
+ }
185
+
186
+
187
+ class _GesturePainter extends CustomPainter {
188
+ const _GesturePainter ({
189
+ this .zoom,
190
+ this .offset,
191
+ this .swatch,
192
+ this .forward,
193
+ this .scaleEnabled,
194
+ this .tapEnabled,
195
+ this .doubleTapEnabled,
196
+ this .longPressEnabled,
197
+ });
198
+
199
+ final double zoom;
200
+ final Offset offset;
201
+ final MaterialColor swatch;
202
+ final bool forward;
203
+ final bool scaleEnabled;
204
+ final bool tapEnabled;
205
+ final bool doubleTapEnabled;
206
+ final bool longPressEnabled;
207
+
208
+ @override
209
+ void paint (Canvas canvas, Size size){
210
+ final Offset center = size.center (Offset .zero)* zoom + offset;
211
+ final double radius = size.width / 2.0 * zoom;
212
+ final Gradient gradient = RadialGradient (
213
+ colors: forward ? < Color > [swatch.shade50, swatch.shade900]
214
+ : < Color > [swatch.shade900, swatch.shade50]
215
+ );
216
+
217
+ final Paint paint = Paint ()
218
+ ..shader = gradient.createShader (Rect .fromCircle (
219
+ center: center,
220
+ radius: radius,
221
+ ));
222
+ canvas.drawCircle (center, radius, paint);
223
+ }
224
+
225
+ @override
226
+ bool shouldRepaint (_GesturePainter oldPainter){
227
+ return oldPainter.zoom != zoom
228
+ || oldPainter.offset != offset
229
+ || oldPainter.swatch != swatch
230
+ || oldPainter.forward != forward
231
+ || oldPainter.scaleEnabled != scaleEnabled
232
+ || oldPainter.tapEnabled != tapEnabled
233
+ || oldPainter.longPressEnabled != longPressEnabled
234
+ || oldPainter.doubleTapEnabled != doubleTapEnabled;
235
+ }
236
+ }
0 commit comments