diff --git a/examples/api/lib/cupertino/date_picker/cupertino_timer_picker.0.dart b/examples/api/lib/cupertino/date_picker/cupertino_timer_picker.0.dart new file mode 100644 index 00000000000..69b660fc2a6 --- /dev/null +++ b/examples/api/lib/cupertino/date_picker/cupertino_timer_picker.0.dart @@ -0,0 +1,132 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flutter code sample for CupertinoTimerPicker + +import 'package:flutter/cupertino.dart'; + +void main() => runApp(const MyApp()); + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + static const String _title = 'CupertinoTimerPicker Sample'; + + @override + Widget build(BuildContext context) { + return const CupertinoApp( + title: _title, + home: CupertinoTimerPickerSample(), + ); + } +} + +class CupertinoTimerPickerSample extends StatefulWidget { + const CupertinoTimerPickerSample({Key? key}) : super(key: key); + + @override + State createState() => _CupertinoTimerPickerSampleState(); +} + +class _CupertinoTimerPickerSampleState extends State { + Duration duration = const Duration(hours: 1, minutes: 23); + + // This shows a CupertinoModalPopup with a reasonable fixed height which hosts CupertinoTimerPicker. + void _showDialog(Widget child) { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) => Container( + height: 216, + padding: const EdgeInsets.only(top: 6.0), + // The Bottom margin is provided to align the popup above the system navigation bar. + margin: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + // Provide a background color for the popup. + color: CupertinoColors.systemBackground.resolveFrom(context), + // Use a SafeArea widget to avoid system overlaps. + child: SafeArea( + top: false, + child: child, + ), + ) + ); + } + + @override + Widget build(BuildContext context) { + return CupertinoPageScaffold( + child: DefaultTextStyle( + style: TextStyle( + color: CupertinoColors.label.resolveFrom(context), + fontSize: 22.0, + ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _TimerPickerItem( + children: [ + const Text('Timer'), + CupertinoButton( + // Display a CupertinoTimerPicker with hour/minute mode. + onPressed: () => _showDialog( + CupertinoTimerPicker( + mode: CupertinoTimerPickerMode.hm, + initialTimerDuration: duration, + // This is called when the user changes the timer duration. + onTimerDurationChanged: (Duration newDuration) { + setState(() => duration = newDuration); + }, + ), + ), + // In this example, the timer value is formatted manually. You can use intl package + // to format the value based on user's locale settings. + child: Text('$duration', + style: const TextStyle( + fontSize: 22.0, + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); + } +} + +// This class simply decorates a row of widgets. +class _TimerPickerItem extends StatelessWidget { + const _TimerPickerItem({required this.children}); + + final List children; + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: const BoxDecoration( + border: Border( + top: BorderSide( + color: CupertinoColors.inactiveGray, + width: 0.0, + ), + bottom: BorderSide( + color: CupertinoColors.inactiveGray, + width: 0.0, + ), + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: children, + ), + ), + ); + } +} diff --git a/examples/api/test/cupertino/date_picker/cupertino_timer_picker.0_test.dart b/examples/api/test/cupertino/date_picker/cupertino_timer_picker.0_test.dart new file mode 100644 index 00000000000..328b04c6428 --- /dev/null +++ b/examples/api/test/cupertino/date_picker/cupertino_timer_picker.0_test.dart @@ -0,0 +1,33 @@ +// Copyright 2014 The Flutter 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_api_samples/cupertino/date_picker/cupertino_timer_picker.0.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +const Offset _kRowOffset = Offset(0.0, -50.0); + +void main() { + testWidgets('Can pick a duration from CupertinoTimerPicker', (WidgetTester tester) async { + await tester.pumpWidget( + const example.MyApp(), + ); + + // Launch the timer picker. + await tester.tap(find.text('1:23:00.000000')); + await tester.pumpAndSettle(); + + // Drag hour, minute to change the time. + await tester.drag(find.text('1'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file + await tester.drag(find.text('23'), _kRowOffset, touchSlopY: 0, warnIfMissed: false); // see top of file + + await tester.pump(); + await tester.pump(const Duration(milliseconds: 500)); + + // Close the timer picker. + await tester.tapAt(const Offset(1.0, 1.0)); + await tester.pumpAndSettle(); + + expect(find.text('3:25:00.000000'), findsOneWidget); + }); +} diff --git a/packages/flutter/lib/src/cupertino/date_picker.dart b/packages/flutter/lib/src/cupertino/date_picker.dart index b2077357074..83172d718f7 100644 --- a/packages/flutter/lib/src/cupertino/date_picker.dart +++ b/packages/flutter/lib/src/cupertino/date_picker.dart @@ -1496,6 +1496,12 @@ enum CupertinoTimerPickerMode { /// provides more space than it needs, the picker will position itself according /// to its [alignment] property. /// +/// {@tool dartpad} +/// This example shows a [CupertinoTimerPicker] that returns a countdown duration. +/// +/// ** See code in examples/api/lib/cupertino/date_picker/cupertino_timer_picker.0.dart ** +/// {@end-tool} +/// /// See also: /// /// * [CupertinoDatePicker], the class that implements different display modes