setState() called after dispose()

Just check boolean property mounted of the state class of your widget before calling setState().

if (this.mounted) {
  setState(() {
    // Your state change code goes here
  });
}

Or even more clean approach Override setState method in your StatelfulWidget class.

class DateTimeButton extends StatefulWidget {
  @override
  void setState(fn) {
    if(mounted) {
      super.setState(fn);
    }
  }
}

If it is an expected behavior that the Future completes when the widget already got disposed you can use

if (mounted) {
  setState(() {
    selectedDate = new DateTime(selectedDate.year, selectedDate.month, selectedDate.day, picked.hour, picked.minute);
  });
}

Just write one line before setState()

 if (!mounted) return;

and then

setState(() {
      //Your code
    });

I had the same problem and i solved changing the super constructor call order on initState():

Wrong code:

@override
  void initState() {
    foo_bar(); // in foo_bar i call setState();
    super.initState(); // state initialization after foo_bar()
  }

Right code:

@override
  void initState() {
    super.initState();
    foo_bar(); // first call super constructor then foo_bar that contains setState() call
  }