cat

dabaicai has a cat

0%

Untitled

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
  @override
Widget build(BuildContext context) {
var gestures = <Type, GestureRecognizerFactory>{
TapGestureRecognizer: GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
() => TapGestureRecognizer(),
(TapGestureRecognizer instance) {
instance.onTapDown = _tapDown;
<!--more-->
instance.onTapUp = _tapUp;
instance.onTap = _tap;
instance.onTapCancel = _tapCancel;
},
),
};
return RawGestureDetector(
gestures: gestures,
child: Container(
width: 100.0,
height: 100.0,
color: color,
alignment: Alignment.center,
child: Text(
"action:$action",
style: TextStyle(color: Colors.white),
)),
);
}
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
RawGestureDetector

@override
void initState() {
super.initState();
_semantics = widget.semantics ?? _DefaultSemanticsGestureDelegate(this);
_syncAll(widget.gestures);
}

@override
Widget build(BuildContext context) {
Widget result = Listener(
onPointerDown: _handlePointerDown,
onPointerPanZoomStart: _handlePointerPanZoomStart,
behavior: widget.behavior ?? _defaultBehavior,
child: widget.child,
);
if (!widget.excludeFromSemantics) {
result = _GestureSemantics(
behavior: widget.behavior ?? _defaultBehavior,
assignSemantics: _updateSemanticsForRenderObject,
child: result,
);
}
return result;
}

点击事件会进入 _handlePointerDown 中

void _handlePointerDown(PointerDownEvent event) {
assert(_recognizers != null);
for (final GestureRecognizer recognizer in _recognizers!.values) {
recognizer.addPointer(event);
}
}


到父类 GestureRecognizer 中

void addPointer(PointerDownEvent event) {
_pointerToKind[event.pointer] = event.kind;
if (isPointerAllowed(event)) {
addAllowedPointer(event);
} else {
handleNonAllowedPointer(event);
}
}


@override
void addAllowedPointer(PointerDownEvent event) {
assert(event != null);
if (state == GestureRecognizerState.ready) {
// If there is no result in the previous gesture arena,
// we ignore them and prepare to accept a new pointer.
if (_down != null && _up != null) {
assert(_down!.pointer == _up!.pointer);
_reset();
}

assert(_down == null && _up == null);
// `_down` must be assigned in this method instead of `handlePrimaryPointer`,
// because `acceptGesture` might be called before `handlePrimaryPointer`,
// which relies on `_down` to call `handleTapDown`.
_down = event;
}
if (_down != null) {
// This happens when this tap gesture has been rejected while the pointer
// is down (i.e. due to movement), when another allowed pointer is added,
// in which case all pointers are simply ignored. The `_down` being null
// means that _reset() has been called, since it is always set at the
// first allowed down event and will not be cleared except for reset(),
super.addAllowedPointer(event);
}
}

>>>>>>>>>> PrimaryPointerGestureRecognizer

@override
void addAllowedPointer(PointerDownEvent event) {
super.addAllowedPointer(event);
if (state == GestureRecognizerState.ready) {
_state = GestureRecognizerState.possible;
_primaryPointer = event.pointer;
_initialPosition = OffsetPair(local: event.localPosition, global: event.position);
if (deadline != null) {
_timer = Timer(deadline!, () => didExceedDeadlineWithEvent(event));
}
}
}

>>>>>>>>>> OneSequenceGestureRecognizer

@override
@protected
void addAllowedPointer(PointerDownEvent event) {
startTrackingPointer(event.pointer, event.transform);
}

@protected
void startTrackingPointer(int pointer, [Matrix4? transform]) {
// 点击事件处理由 handleEvent 函数完成
GestureBinding.instance.pointerRouter.addRoute(pointer, handleEvent, transform);
_trackedPointers.add(pointer);
assert(!_entries.containsValue(pointer));
// _addPointerToArena(pointer) 应该是将 pointer 加入到手势竞技场中
// _entries 里面有竞技场相关的东西,之后通过 pointer 取出竞技场开始竞争
_entries[pointer] = _addPointerToArena(pointer);
}

GestureArenaEntry _addPointerToArena(int pointer) {
if (_team != null) {
return _team!.add(pointer, this);
}
return GestureBinding.instance.gestureArena.add(pointer, this);
}

// GestureBinding 中会初始化 GestureArenaManager
GestureArenaEntry add(int pointer, GestureArenaMember member) {
final _GestureArena state = _arenas.putIfAbsent(pointer, () {
assert(_debugLogDiagnostic(pointer, '★ Opening new gesture arena.'));
return _GestureArena();
});
state.add(member);
assert(_debugLogDiagnostic(pointer, 'Adding: $member'));
return GestureArenaEntry._(this, pointer, member);
}


之后再回到 PrimaryPointerGestureRecognizer 中的 addAllowedPointer 方法中

@override
void addAllowedPointer(PointerDownEvent event) {
super.addAllowedPointer(event);
if (state == GestureRecognizerState.ready) {
_state = GestureRecognizerState.possible;
_primaryPointer = event.pointer;
_initialPosition = OffsetPair(local: event.localPosition, global: event.position);
if (deadline != null) {
// deadline = 100 ms
// 就是说 100ms 之后会会执行 didExceedDeadlineWithEvent 这个方法
_timer = Timer(deadline!, () => didExceedDeadlineWithEvent(event));
}
}
}

@protected
void didExceedDeadlineWithEvent(PointerDownEvent event) {
didExceedDeadline();
}

void _checkDown() {
if (_sentTapDown) {
return;
}
handleTapDown(down: _down!);
_sentTapDown = true;
}

@protected
@override
void handleTapDown({required PointerDownEvent down}) {
final TapDownDetails details = TapDownDetails(
globalPosition: down.position,
localPosition: down.localPosition,
kind: getKindForPointer(down.pointer),
);
switch (down.buttons) {
case kPrimaryButton:
if (onTapDown != null) {
// 执行 onTapDown 方法,也就是在一开始构造函数中传入的回调方法
invokeCallback<void>('onTapDown', () => onTapDown!(details));
}
break;
......
}
}


最后分析 OneSequenceGestureRecognizer 中 startTrackingPointer 方法中的 handleEvent 方法
@override
void handleEvent(PointerEvent event) {
assert(state != GestureRecognizerState.ready);
if (state == GestureRecognizerState.possible && event.pointer == primaryPointer) {
// !_gestureAccepted && 移动的距离大余 18
final bool isPreAcceptSlopPastTolerance =
!_gestureAccepted && // 接受手势或者停止检测才会是 true
preAcceptSlopTolerance != null && // 18
_getGlobalDistance(event) > preAcceptSlopTolerance!;
// _gestureAccepted && 移动的距离大余 18
final bool isPostAcceptSlopPastTolerance =
_gestureAccepted &&
postAcceptSlopTolerance != null && // 18
_getGlobalDistance(event) > postAcceptSlopTolerance!;

// 点击手势走 else ,移动手势走 if
if (event is PointerMoveEvent && (isPreAcceptSlopPastTolerance || isPostAcceptSlopPastTolerance)) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(primaryPointer!);
} else {
handlePrimaryPointer(event);
}
}
stopTrackingIfPointerNoLongerDown(event);
}

@override
void handlePrimaryPointer(PointerEvent event) {
if (event is PointerUpEvent) {
_up = event;
// 回调构造时闯进来的回调函数,完成本次事件
_checkUp();
} else if (event is PointerCancelEvent) {
resolve(GestureDisposition.rejected);
if (_sentTapDown) {
_checkCancel(event, '');
}
_reset();
} else if (event.buttons != _down!.buttons) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(primaryPointer!);
}
}