showDurationPicker function

Future<Duration?> showDurationPicker({
  1. required BuildContext context,
  2. Duration initialDuration = Duration.zero,
  3. String? helpText,
})

A styled duration picker.

final Duration? duration = await showDurationPicker(
  context: context,
  initialDuration: Duration(hours: 1),
)

Implementation

Future<Duration?> showDurationPicker({
  required BuildContext context,
  Duration initialDuration = Duration.zero,
  String? helpText,
}) async {
  int hours = initialDuration.inHours;
  int minutes = initialDuration.inMinutes.remainder(60);

  final ColorScheme scheme = Theme.of(context).colorScheme;

  final bool? confirmed = await showDialog<bool>(
    context: context,
    builder: (BuildContext context) => StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) => AlertDialog(
        backgroundColor: scheme.surfaceContainerLow,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(AppRadius.extraLarge),
        ),
        title: Text(helpText ?? 'Select Duration'),
        content: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _DurationColumn(
              label: 'H',
              value: hours,
              onChanged: (int v) => setState(() => hours = v),
            ),
            const Padding(
              padding: EdgeInsets.symmetric(horizontal: 8),
              child: Text(':',
                  style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
            ),
            _DurationColumn(
              label: 'M',
              value: minutes,
              max: 59,
              onChanged: (int v) => setState(() => minutes = v),
            ),
          ],
        ),
        actions: <Widget>[
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('Cancel'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(context).pop(true),
            child: const Text('OK'),
          ),
        ],
      ),
    ),
  );

  if (confirmed == true) {
    return Duration(hours: hours, minutes: minutes);
  }
  return null;
}