Skip to content

Commit 7710b5d

Browse files
button: Replace GestureDetector with Listener for AnimatedScaleOnTap
Fixes zulip#1953. Latter provides instant scaleDown animation on tap, unlike GestureDetector which has a `kPressTimeOut` causing delay of 100ms https://main-api.flutter.dev/flutter/gestures/kPressTimeout-constant.html
1 parent 80f5a85 commit 7710b5d

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

lib/widgets/button.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,11 @@ class _AnimatedScaleOnTapState extends State<AnimatedScaleOnTap> {
303303

304304
@override
305305
Widget build(BuildContext context) {
306-
return GestureDetector(
306+
return Listener(
307307
behavior: HitTestBehavior.translucent,
308-
onTapDown: (_) => _changeScale(widget.scaleEnd),
309-
onTapUp: (_) => _changeScale(1),
310-
onTapCancel: () => _changeScale(1),
308+
onPointerDown: (_) => _changeScale(widget.scaleEnd),
309+
onPointerUp: (_) => _changeScale(1),
310+
onPointerCancel: (_) => _changeScale(1),
311311
child: AnimatedScale(
312312
scale: _scale,
313313
duration: widget.duration,

test/widgets/button_test.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,39 @@ void main() {
114114
check(renderObject).size.equals(Size.square(40));
115115
});
116116

117+
group('AnimatedScaleOnTap', () {
118+
void checkScale(WidgetTester tester, Finder finder, double expectedScale) {
119+
final scale = tester.widget<AnimatedScale>(finder).scale;
120+
check(scale).equals(expectedScale);
121+
}
122+
123+
testWidgets('Animation happen instantly when tap down', (tester) async {
124+
addTearDown(testBinding.reset);
125+
126+
await tester.pumpWidget(TestZulipApp(
127+
child: AnimatedScaleOnTap(
128+
scaleEnd: 0.95,
129+
duration: Duration(milliseconds: 100),
130+
child: UnconstrainedBox(
131+
child: ZulipIconButton(
132+
icon: ZulipIcons.follow,
133+
onPressed: () {})))));
134+
await tester.pump();
135+
136+
final animatedScaleFinder = find.byType(AnimatedScale);
137+
138+
// Now that the widget is being held down, its scale should be at the target scaleEnd i.e 0.95.
139+
final gesture = await tester.startGesture(tester.getCenter(find.byType(ZulipIconButton)));
140+
await tester.pumpAndSettle();
141+
checkScale(tester, animatedScaleFinder, 0.95);
142+
143+
// After releasing, the scale must return to 1.0.
144+
await gesture.up();
145+
await tester.pumpAndSettle();
146+
checkScale(tester, animatedScaleFinder, 1.0);
147+
});
148+
});
149+
117150
// TODO test that the touch feedback fills the whole square
118151
});
119152
}

0 commit comments

Comments
 (0)