From 41fb069cb78412c58709ce00c8e755ed47de9d70 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Wed, 23 May 2018 09:49:14 -0700 Subject: [PATCH] Prevent Switch from looping on and off (#17821) --- .../flutter/lib/src/material/toggleable.dart | 22 ++++++---- .../flutter/test/material/switch_test.dart | 41 +++++++++++++++++++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/packages/flutter/lib/src/material/toggleable.dart b/packages/flutter/lib/src/material/toggleable.dart index ae04cecd16..a09a0227b5 100644 --- a/packages/flutter/lib/src/material/toggleable.dart +++ b/packages/flutter/lib/src/material/toggleable.dart @@ -134,13 +134,20 @@ abstract class RenderToggleable extends RenderConstrainedBox { _position ..curve = Curves.easeIn ..reverseCurve = Curves.easeOut; - switch (_positionController.status) { - case AnimationStatus.forward: - case AnimationStatus.completed: - _positionController.reverse(); - break; - default: + if (tristate) { + switch (_positionController.status) { + case AnimationStatus.forward: + case AnimationStatus.completed: + _positionController.reverse(); + break; + default: + _positionController.forward(); + } + } else { + if (value == true) _positionController.forward(); + else + _positionController.reverse(); } } @@ -257,8 +264,7 @@ abstract class RenderToggleable extends RenderConstrainedBox { if (isInteractive && !tristate) { if (status == AnimationStatus.completed && _value == false) { onChanged(true); - } - else if (status == AnimationStatus.dismissed && _value != false) { + } else if (status == AnimationStatus.dismissed && _value != false) { onChanged(false); } } diff --git a/packages/flutter/test/material/switch_test.dart b/packages/flutter/test/material/switch_test.dart index 8238f6dc0c..38eb5fcfc9 100644 --- a/packages/flutter/test/material/switch_test.dart +++ b/packages/flutter/test/material/switch_test.dart @@ -187,4 +187,45 @@ void main() { ..circle(color: Colors.red[500]) ); }); + + testWidgets('Drag ends after animation completes', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/17773 + + bool value = false; + await tester.pumpWidget( + new Directionality( + textDirection: TextDirection.ltr, + child: new StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return new Material( + child: new Center( + child: new Switch( + value: value, + onChanged: (bool newValue) { + setState(() { + value = newValue; + }); + }, + ), + ), + ); + }, + ), + ), + ); + + expect(value, isFalse); + + final Rect switchRect = tester.getRect(find.byType(Switch)); + final TestGesture gesture = await tester.startGesture(switchRect.centerLeft); + await tester.pump(); + await gesture.moveBy(new Offset(switchRect.width, 0.0)); + await tester.pump(); + await gesture.up(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 200)); + + expect(value, isTrue); + expect(tester.hasRunningAnimations, false); + }); }