1

how can I get the selected time of TimePickerDialog in Flutter? I dont want to use showDialog because I want to add some other buttons below the TimePickerDialog. When it is not possible to use the TimePickerDialog then what would be the way to do it? Use the sourcecode of Timepickerdialog in my local workspace and update it there? I am using it like this:

showDialog(
  context: context,
  builder: (BuildContext context) {
    return AlertDialog(
      actions: <Widget>[
        SizedBox(
          child: TimePickerDialog(
            initialTime: TimeOfDay.fromDateTime(DateTime.now()),
            cancelText: "",
            confirmText: "", 
          ),
        ),
        TextButton(
          child: Text('Cancel'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
        TextButton(
          child: Text('OK'),
          onPressed: () {
            // Perform an action
            Navigator.of(context).pop();
          },
        ),
      ],
    );
  },
);

picture

otto
  • 1,815
  • 7
  • 37
  • 63

2 Answers2

1

According to the official docs here, the value returned by showDialog is the selected TimeOfDay if the user taps the "OK" button, or null if the user taps the "CANCEL" button.

So you need to call the showDialog with the await keyword.

final selectedTime = await showDialog(
  context: context,
  builder: (BuildContext context) {
    return AlertDialog(
      actions: <Widget>[
        SizedBox(
          child: TimePickerDialog(
            initialTime: TimeOfDay.fromDateTime(DateTime.now()),
            cancelText: "",
            confirmText: "", 
          ),
        ),
        TextButton(
          child: Text('Cancel'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
        TextButton(
          child: Text('OK'),
          onPressed: () {
            // Perform an action
            Navigator.of(context).pop();
          },
        ),
      ],
    );
  },
);

Waseem Abbas
  • 341
  • 1
  • 6
  • 1
    thats looks promising, but I hide the official OK und Cancel Button. Will I also get the time when I close the time with my TextButtons? – otto Jun 15 '23 at 07:24
  • tried it out and the selectedTime is always null because I am hiding the OK and Cancel Button – otto Jun 15 '23 at 16:41
1

The solution to the question is straightforward, we just have to make changes inside the timer_picker.dart file.

Open timer_picker.dart file by hovering over the TimePickerDialog widget and hold CTRL and left-click on it, this will open timer_picker. In this file scroll to line no 2415. Then just copy paste the code which I have added below. Hot restart the app after saving the file

Note : - Any UI or function changes related to timerPicker Widget need to be changed inside the timer_picker.dart file.

Complete Code : -

UI Code : -

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const Box(),
    );
  }
}

class Box extends StatefulWidget {
  const Box({super.key});

  @override
  State<Box> createState() => _BoxState();
}

class _BoxState extends State<Box> {
  var timeVal = TimeOfDay.fromDateTime(DateTime.now());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: GestureDetector(
      onTap: () async {
        timeVal = await showDialog(
          context: context,
          builder: (BuildContext context) {
            return TimePickerDialog(
              initialTime: timeVal,
              cancelText: "",
              confirmText: "",
            );
          },
        );
        setState(() {});
      },
      child: Text(
        "Time : - ${timeVal.format(context)}",
        style: const TextStyle(fontSize: 25),
      ),
    )));
  }
}

time_picker.dart Code : -

return AlertDialog(
  actions: <Widget>[
    SizedBox(
        height: 500,
        width: 500,
        child: WillPopScope(
            onWillPop: () {
              _handleOk();
              return Future.value(false);
            },
            child: Dialog(
              shape: shape,
              elevation: pickerTheme.elevation ?? defaultTheme.elevation,
              backgroundColor: pickerTheme.backgroundColor ??
                  defaultTheme.backgroundColor,
              insetPadding: EdgeInsets.symmetric(
                horizontal: 16,
                vertical: (_entryMode.value == TimePickerEntryMode.input ||
                        _entryMode.value == TimePickerEntryMode.inputOnly)
                    ? 0
                    : 24,
              ),
              child: Padding(
                padding: pickerTheme.padding ?? defaultTheme.padding,
                child: LayoutBuilder(builder:
                    (BuildContext context, BoxConstraints constraints) {
                  final Size constrainedSize =
                      constraints.constrain(dialogSize);
                  final Size allowedSize = Size(
                    constrainedSize.width < minDialogSize.width
                        ? minDialogSize.width
                        : constrainedSize.width,
                    constrainedSize.height < minDialogSize.height
                        ? minDialogSize.height
                        : constrainedSize.height,
                  );
                  return SingleChildScrollView(
                    restorationId: 'time_picker_scroll_view_horizontal',
                    scrollDirection: Axis.horizontal,
                    child: SingleChildScrollView(
                      restorationId: 'time_picker_scroll_view_vertical',
                      child: AnimatedContainer(
                        width: allowedSize.width,
                        height: allowedSize.height,
                        duration: _kDialogSizeAnimationDuration,
                        curve: Curves.easeIn,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Expanded(
                              child: Form(
                                key: _formKey,
                                autovalidateMode: _autovalidateMode.value,
                                child: _TimePicker(
                                  time: widget.initialTime,
                                  onTimeChanged: _handleTimeChanged,
                                  helpText: widget.helpText,
                                  cancelText: widget.cancelText,
                                  confirmText: widget.confirmText,
                                  errorInvalidText: widget.errorInvalidText,
                                  hourLabelText: widget.hourLabelText,
                                  minuteLabelText: widget.minuteLabelText,
                                  restorationId: 'time_picker',
                                  entryMode: _entryMode.value,
                                  orientation: widget.orientation,
                                  onEntryModeChanged:
                                      _handleEntryModeChanged,
                                ),
                              ),
                            ),
                            actions,
                          ],
                        ),
                      ),
                    ),
                  );
                }),
              ),
            ))),
    TextButton(
      child: const Text('Cancel'),
      onPressed: () {
        _handleOk();
      },
    ),
  ],
);
  }
}

Output : -

Ramji
  • 904
  • 2
  • 5
  • 20
  • Thanks thats nearly what I want, but when I use Button like this to close the Dialog I get null for the selected Time TextButton( child: Text('Cancel'), onPressed: () { Navigator.of(context).pop(); }, ), – otto Jun 21 '23 at 20:07