Flutter - CupertinoDatePicker initialDateTime updates only once

1,720

CupertinoDatePicker is maintaining state internally and only set the initialDateTime on its initState, despite you updating your widget's state.

To force a rebuild each time you set your initialDateTime, assign an UniqueKey() as a key of your CupertinoDatePicker and it will rebuild every time your state changes with a new initDateTime.

(...)
  CupertinoDatePicker(
        key: UniqueKey(),
        mode: CupertinoDatePickerMode.time,
        use24hFormat: true,
        initialDateTime: initDateTime,
        backgroundColor: Colors.transparent,
        onDateTimeChanged: (DateTime date) {
          //
        },
      ),
Share:
1,720
user6097845
Author by

user6097845

Updated on December 22, 2022

Comments

  • user6097845
    user6097845 over 1 year

    I've created a CupertinoDatePicker widget, with an initial value set to a variable.

    I want to update the selected value in the picker to that variable value when the user clicks on another widget in the screen - but it doesn't work (although the CupertinoDatePicker widget gets rebuilt).

    Is it a bug or am I doing something wrong?

    Code (can be copy-pasted into dartPad):

    import 'package:flutter/material.dart';
    import 'package:flutter/cupertino.dart';
    
    final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
    final _time = DateTime.now();
    int _min = 5;
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
              child: MyWidget(),
            ),
          ),
        );
      }
    }
    
    class MyWidget extends StatefulWidget {
      @override
      createState() => MyWidgetSate();
    }
    
    class MyWidgetSate extends State<MyWidget> {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Text('_min = ' + _min.toString(), style: Theme.of(context).textTheme.headline4),
            _buildDurationPicker(context),
            RaisedButton(
                onPressed: () {
                  print('hello');
                  setState(() {
                    _min += 5;
                  });
                },
                child: const Text('Add', style: TextStyle(fontSize: 20)),
              ),
            ],
        );
      }
    }
    
    Widget _buildDurationPicker(BuildContext context) {
        DateTime initDateTime = DateTime(_time.year, _time.month, _time.day)
            .add(Duration(minutes: _min));
        return Container(
          height: 216.0,
          color: Colors.white,
          child: CupertinoDatePicker(
            mode: CupertinoDatePickerMode.time,
            use24hFormat: true,
            initialDateTime: initDateTime,
            backgroundColor: Colors.transparent,
            onDateTimeChanged: (DateTime date) {
              //
            },
          ),
        );
      }
    
    • C. Lewis
      C. Lewis almost 4 years
      Can you please post the full Widget code, or get a minimum working example up on DartPad?
    • user6097845
      user6097845 almost 4 years
      Sure, updated my question to include a working sample (can be copied into dartPad)
  • Olek L.
    Olek L. over 2 years
    Thank you very much, you saved a lot of my time!