Skip to content

Conversation

@MritunjayTiwari14
Copy link
Contributor

@MritunjayTiwari14 MritunjayTiwari14 commented Oct 30, 2025

Fixes #1953.

The Scale down and Scale up as well as Ink Splash animation occurs after a finite delay of 100ms. Mainly due to GestureDetector used inside AnimatedScaleOnTap.

This can be fixed by using Listener hence replacing the GestureDetector inside AnimatedScaleOnTap.

Discussion: #mobile > issue in responsiveness of home bottom navbar icons
Design: Figma Design

Comparison Through Video of Fix-up

Before

implementation.mp4

After

fixup.mp4

@gnprice gnprice added the maintainer review PR ready for review by Zulip maintainers label Oct 30, 2025
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
Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Comments below.

check(scale).equals(expectedScale);
}

testWidgets('Animation happen instantly when tap down', (tester) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I run this test without your change in lib/widgets/button.dart, it still passes. That means it's not doing its job.

Comment on lines +306 to +310
return Listener(
behavior: HitTestBehavior.translucent,
onTapDown: (_) => _changeScale(widget.scaleEnd),
onTapUp: (_) => _changeScale(1),
onTapCancel: () => _changeScale(1),
onPointerDown: (_) => _changeScale(widget.scaleEnd),
onPointerUp: (_) => _changeScale(1),
onPointerCancel: (_) => _changeScale(1),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From reading the docs for GestureDetector.onTapDown and friends, it looks like one of the helpful features of that higher-level API is that it only considers pointer events from a "primary button". I don't know how common it is e.g. to use a stylus with multiple buttons, but this seems like functionality that would be helpful to keep.

The event passed to the Listener.onPointerDown callback (etc.) has a buttons field. So in each of the handlers, let's check whether the event's buttons field equals kPrimaryButton, and only respond if it does.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the name and dartdoc of this AnimatedScaleOnTap should be updated to match the new behavior: it's no longer about a tap gesture, which is only recognized after 100ms. For example:

/// Apply [Transform.scale] to the child widget on primary pointer-down,
/// and reset its scale on -up or -cancel, with animated transitions.
class AnimatedScaleOnPointerDown extends StatefulWidget {

@chrisbobbe chrisbobbe self-assigned this Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer review PR ready for review by Zulip maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

button: Delayed tap feedback on bottom nav and menu buttons

3 participants