Animate a CupertinoButton based on tap move events only if the move happens between a tap down and a tap up (#165729)
Fixes https://github.com/flutter/flutter/issues/165724
This commit is contained in:
@@ -356,8 +356,10 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
||||
}
|
||||
|
||||
bool _buttonHeldDown = false;
|
||||
bool _tapInProgress = false;
|
||||
|
||||
void _handleTapDown(TapDownDetails event) {
|
||||
_tapInProgress = true;
|
||||
if (!_buttonHeldDown) {
|
||||
_buttonHeldDown = true;
|
||||
_animate();
|
||||
@@ -365,6 +367,7 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
||||
}
|
||||
|
||||
void _handleTapUp(TapUpDetails event) {
|
||||
_tapInProgress = false;
|
||||
if (_buttonHeldDown) {
|
||||
_buttonHeldDown = false;
|
||||
_animate();
|
||||
@@ -377,19 +380,20 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
||||
}
|
||||
|
||||
void _handleTapCancel() {
|
||||
_tapInProgress = false;
|
||||
if (_buttonHeldDown) {
|
||||
_buttonHeldDown = false;
|
||||
_animate();
|
||||
}
|
||||
}
|
||||
|
||||
void _handTapMove(TapMoveDetails event) {
|
||||
void _handleTapMove(TapMoveDetails event) {
|
||||
final RenderBox renderObject = context.findRenderObject()! as RenderBox;
|
||||
final Offset localPosition = renderObject.globalToLocal(event.globalPosition);
|
||||
final bool buttonShouldHeldDown = renderObject.paintBounds
|
||||
.inflate(CupertinoButton.tapMoveSlop())
|
||||
.contains(localPosition);
|
||||
if (buttonShouldHeldDown != _buttonHeldDown) {
|
||||
if (_tapInProgress && buttonShouldHeldDown != _buttonHeldDown) {
|
||||
_buttonHeldDown = buttonShouldHeldDown;
|
||||
_animate();
|
||||
}
|
||||
@@ -512,7 +516,7 @@ class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProv
|
||||
instance.onTapDown = enabled ? _handleTapDown : null;
|
||||
instance.onTapUp = enabled ? _handleTapUp : null;
|
||||
instance.onTapCancel = enabled ? _handleTapCancel : null;
|
||||
instance.onTapMove = enabled ? _handTapMove : null;
|
||||
instance.onTapMove = enabled ? _handleTapMove : null;
|
||||
instance.gestureSettings = gestureSettings;
|
||||
},
|
||||
),
|
||||
|
||||
@@ -912,6 +912,30 @@ void main() {
|
||||
expect(opacity.opacity.value, 0.4);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('Drag outside button within ListView does not leave the button pressed', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
await tester.pumpWidget(
|
||||
boilerplate(
|
||||
child: ListView(
|
||||
children: <Widget>[CupertinoButton(onPressed: () {}, child: const Text('Tap me'))],
|
||||
),
|
||||
),
|
||||
);
|
||||
final FadeTransition opacity = tester.widget(
|
||||
find.descendant(of: find.byType(CupertinoButton), matching: find.byType(FadeTransition)),
|
||||
);
|
||||
|
||||
final TestGesture gesture = await tester.createGesture();
|
||||
addTearDown(gesture.removePointer);
|
||||
|
||||
await gesture.down(tester.getTopLeft(find.byType(CupertinoButton)));
|
||||
await gesture.moveBy(const Offset(1, 1));
|
||||
await gesture.moveBy(Offset(0, -CupertinoButton.tapMoveSlop() - 5));
|
||||
await tester.pumpAndSettle();
|
||||
expect(opacity.opacity.value, 1.0);
|
||||
});
|
||||
|
||||
testWidgets('onPressed trigger takes into account MoveSlop.', (WidgetTester tester) async {
|
||||
bool value = false;
|
||||
await tester.pumpWidget(
|
||||
|
||||
Reference in New Issue
Block a user