From 0f1dbe09af20cdeea5d433f67bc3e20da5774536 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Wed, 27 Apr 2016 12:26:18 -0700 Subject: [PATCH] Fixes TimePicker (#3583) * Fixed TimePicker crash and added tests * Fixed TimePicker crash and added tests * fixed a Lint-O --- .../flutter/lib/src/material/time_picker.dart | 10 +- .../test/material/time_picker_test.dart | 126 ++++++++++++++++++ 2 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 packages/flutter/test/material/time_picker_test.dart diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart index 5fb1ec1631e..36a574825d2 100644 --- a/packages/flutter/lib/src/material/time_picker.dart +++ b/packages/flutter/lib/src/material/time_picker.dart @@ -106,9 +106,10 @@ enum _TimePickerMode { hour, minute } /// * class TimePicker extends StatefulWidget { TimePicker({ + Key key, this.selectedTime, this.onChanged - }) { + }) : super(key: key) { assert(selectedTime != null); } @@ -417,10 +418,11 @@ class _DialState extends State<_Dial> { void _updateThetaForPan() { setState(() { - Offset offset = _position - _center; + final Offset offset = _position - _center; + final double angle = (math.atan2(offset.dx, offset.dy) - math.PI / 2.0) % _kTwoPi; _thetaTween - ..begin = (math.atan2(offset.dx, offset.dy) - math.PI / 2.0) % _kTwoPi - ..end = null; + ..begin = angle + ..end = angle; // The controller doesn't animate during the pan gesture. }); } diff --git a/packages/flutter/test/material/time_picker_test.dart b/packages/flutter/test/material/time_picker_test.dart new file mode 100644 index 00000000000..82c24aaecc7 --- /dev/null +++ b/packages/flutter/test/material/time_picker_test.dart @@ -0,0 +1,126 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:test/test.dart'; + +void main() { + test('tap-select an hour', () { + testWidgets((WidgetTester tester) { + Key _timePickerKey = new UniqueKey(); + TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 0); + + tester.pumpWidget( + new StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return new Material( + child: new Center( + child: new SizedBox( + width: 200.0, + height: 400.0, + child: new TimePicker( + key: _timePickerKey, + selectedTime: _selectedTime, + onChanged: (TimeOfDay value) { + setState(() { + _selectedTime = value; + }); + } + ) + ) + ) + ); + } + ) + ); + + Point center = tester.getCenter(find.byKey(_timePickerKey)); + + Point hour0 = new Point(center.x, center.y - 50.0); // 12:00 AM + tester.tapAt(hour0); + expect(_selectedTime.hour, equals(0)); + + Point hour3 = new Point(center.x + 50.0, center.y); + tester.tapAt(hour3); + expect(_selectedTime.hour, equals(3)); + + Point hour6 = new Point(center.x, center.y + 50.0); + tester.tapAt(hour6); + expect(_selectedTime.hour, equals(6)); + + Point hour9 = new Point(center.x - 50.0, center.y); + tester.tapAt(hour9); + expect(_selectedTime.hour, equals(9)); + + tester.pump(const Duration(seconds: 1)); // Finish gesture animation. + tester.pump(const Duration(seconds: 1)); // Finish settling animation. + }); + }); + + test('drag-select an hour', () { + testWidgets((WidgetTester tester) { + Key _timePickerKey = new UniqueKey(); + TimeOfDay _selectedTime = const TimeOfDay(hour: 7, minute: 0); + + tester.pumpWidget( + new StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return new Material( + child: new Center( + child: new SizedBox( + width: 200.0, + height: 400.0, + child: new TimePicker( + key: _timePickerKey, + selectedTime: _selectedTime, + onChanged: (TimeOfDay value) { + setState(() { + _selectedTime = value; + }); + } + ) + ) + ) + ); + } + ) + ); + + Point center = tester.getCenter(find.byKey(_timePickerKey)); + Point hour0 = new Point(center.x, center.y - 50.0); // 12:00 AM + Point hour3 = new Point(center.x + 50.0, center.y); + Point hour6 = new Point(center.x, center.y + 50.0); + Point hour9 = new Point(center.x - 50.0, center.y); + + tester.startGesture(hour3) + ..moveBy(hour0 - hour3) + ..up(); + expect(_selectedTime.hour, equals(0)); + tester.pump(const Duration(seconds: 1)); // Finish gesture animation. + tester.pump(const Duration(seconds: 1)); // Finish settling animation. + + tester.startGesture(hour0) + ..moveBy(hour3 - hour0) + ..up(); + expect(_selectedTime.hour, equals(3)); + tester.pump(const Duration(seconds: 1)); + tester.pump(const Duration(seconds: 1)); + + tester.startGesture(hour3) + ..moveBy(hour6 - hour3) + ..up(); + expect(_selectedTime.hour, equals(6)); + tester.pump(const Duration(seconds: 1)); + tester.pump(const Duration(seconds: 1)); + + tester.startGesture(hour6) + ..moveBy(hour9 - hour6) + ..up(); + expect(_selectedTime.hour, equals(9)); + tester.pump(const Duration(seconds: 1)); + tester.pump(const Duration(seconds: 1)); + }); + }); +}