Vincenzo
Vincenzo

Reputation: 6448

Setting CupertinoDatePicker minuteInterval: throws an exception. Flutter

I'm having trouble setting CupertinoDatePicker's minuteInterval: property to 30. It should be an integer factor of 60, so 30 should be fine. But I'm only able to set it to 1 or 2, any other value throws this exception:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building BlocBuilder<BookingBloc, BookingState>(dirty, state: _BlocBuilderBaseState<BookingBloc, BookingState>#c437f):
initial minute is not divisible by minute interval
'package:flutter/src/cupertino/date_picker.dart':
Failed assertion: line 269 pos 7: 'this.initialDateTime.minute % minuteInterval == 0'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=BUG.md

The relevant error-causing widget was: 
  BlocBuilder<BookingBloc, BookingState> file:///Volumes/archivi%20recuperati/Flutter%20apps%20/fixit_cloud_biking/lib/Screens/select_shop_booking_screen.dart:67:14
When the exception was thrown, this was the stack: 
#2      new CupertinoDatePicker (package:flutter/src/cupertino/date_picker.dart:269:7)
#3      _SelectShopBookingScreenState.build.<anonymous closure> (package:fixit_cloud_biking/Screens/select_shop_booking_screen.dart:132:36)
#4      BlocBuilder.build (package:flutter_bloc/src/bloc_builder.dart:90:50)
#5      _BlocBuilderBaseState.build (package:flutter_bloc/src/bloc_builder.dart:162:48)
#6      StatefulElement.build (package:flutter/src/widgets/framework.dart:4334:27)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

Is there something else to be set to set it right?

This is how I set it up.

Many thanks in advance.

Expanded(
                          flex: 2,
                          child: Container(
                            padding: EdgeInsets.all(20),
                            color: Colors.transparent,
                            child: CupertinoDatePicker(
                                backgroundColor: Colors.transparent,
                                use24hFormat: true,
                                mode: CupertinoDatePickerMode.dateAndTime,
                                minuteInterval: 30,
                                onDateTimeChanged: (DateTime selected) {
                                  print('selected is $selected');
                                  BlocProvider.of<BookingBloc>(context).add(
                                      FindAvailableShopsForBooking(
                                          bookingStart:
                                              selected.millisecondsSinceEpoch,
                                          duration: widget.duration,
                                          cityDb: widget.cityDb,
                                          regionDb: widget.regionDb,
                                          countryDb: widget.countryDb));
                                }),
                          ),
                        ),

Upvotes: 3

Views: 2278

Answers (2)

Volodymyr
Volodymyr

Reputation: 1442

You should update both parameters: minuteInterval and initialDateTime. Here is an example with 30 mins interval:

              SizedBox(
                height: 200,
                child: CupertinoDatePicker(
                  minuteInterval: 30,
                  initialDateTime: DateTime.now().add(
                    Duration(minutes: 30 - DateTime.now().minute % 30),
                  ),
                  mode: CupertinoDatePickerMode.time,
                  use24hFormat: true,
                  onDateTimeChanged: (value) => setState(
                    () {
                      print(value);
                    },
                  ),
                ),
              ),

enter image description here

Upvotes: 6

Vincenzo
Vincenzo

Reputation: 6448

After a few tries and communications on Github we agreed that the assertion which fails if you set minuteInterval: anything but 1 or 2, and throws the error Failed assertion: line 269 pos 7: 'this.initialDateTime.minute % minuteInterval == 0' doesn't really make sense to make sure minuteInterval is an integer factor of 60..

I suggested 60 % minuteInterval == 0' as a fix, because as it is now it makes sure minuteInterval is an integer factor of DateTime.now().minute if you don't specify any DateTime in CupertinoDatePicker initialDateTime: parameter.

So to make it work properly as it is now I did add it and initialized it wit DateTime.now() with minutes at 0 to have the reminder of the assertion correctly 0 as so :

Workaround:

DateTime initialDate;
  @override
  void initState() {
    super.initState();
    DateTime initial = DateTime.now();
    initialDate =
        DateTime(initial.year, initial.month, initial.day, initial.hour, 0);
  }

then passed it to the CupertinoDatePicker :

New CupertinoDatePicker :

CupertinoDatePicker(
                                backgroundColor: Colors.transparent,
                                use24hFormat: true,
                                mode: CupertinoDatePickerMode.dateAndTime,
                                initialDateTime: initialDate,
                                minuteInterval: 30,
                                onDateTimeChanged: (DateTime selected) {
                                  
                                  // do what you need
                                  
                                }),

Upvotes: 3

Related Questions