I have a list of times that are representing breakslots. They are adjustable with the CupertinoDatePicker on a BottomSheet. Every time i try to add a new breakslot with a CupertinoDatePicker i get following error. In Debug Mode it leads me to the Scroll_position.dart and shows me that the _minScrollExtent is null but has a null check (!). Anyone ideas or suggestions how to fix that?
The following _TypeError was thrown building CupertinoDatePicker(dependencies: [Directionality,
MediaQuery, _InheritedCupertinoTheme, _LocalizationsScope-[GlobalKey#45bfe]], state:
_CupertinoDatePickerDateTimeState#e45f1):
Null check operator used on a null value
The relevant error-causing widget was:
CupertinoDatePicker
CupertinoDatePicker:file:///Users/jordanruff/Prio/prio_app/lib/TimeKeeping/components/timekeeping_day_editor.dart:337:24
When the exception was thrown, this was the stack:
#0 ScrollPosition.minScrollExtent (package:flutter/src/widgets/scroll_position.dart:226:49)
#1 _FixedExtentScrollPosition.itemIndex (package:flutter/src/widgets/list_wheel_scroll_view.dart:392:24)
#2 FixedExtentScrollController.selectedItem (package:flutter/src/widgets/list_wheel_scroll_view.dart:251:21)
#3 _CupertinoDatePickerDateTimeState._selectedHourIndex (package:flutter/src/cupertino/date_picker.dart:558:76)
#4 _CupertinoDatePickerDateTimeState.selectedHour (package:flutter/src/cupertino/date_picker.dart:557:55)
#5 _CupertinoDatePickerDateTimeState._buildMinutePicker.<anonymous closure> (package:flutter/src/cupertino/date_picker.dart:896:13)
#6 new _GrowableList.generate (dart:core-patch/growable_array.dart:136:28)
#7 _CupertinoDatePickerDateTimeState._buildMinutePicker (package:flutter/src/cupertino/date_picker.dart:889:19)
#8 _CupertinoDatePickerDateTimeState.build (package:flutter/src/cupertino/date_picker.dart:1076:33)
#9 StatefulElement.build (package:flutter/src/widgets/framework.dart:5409:27)
#10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5297:15)
#11 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
#12 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#13 StatefulElement.update (package:flutter/src/widgets/framework.dart:5485:5)
#14 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#15 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#16 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#17 ProxyElement.update (package:flutter/src/widgets/framework.dart:5628:5)
#18 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#19 Element.updateChildren (package:flutter/src/widgets/framework.dart:3834:32)
#20 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6594:17)
#21 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#22 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#23 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#24 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#25 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#26 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#27 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#28 StatelessElement.update (package:flutter/src/widgets/framework.dart:5373:5)
#29 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#30 Element.updateChildren (package:flutter/src/widgets/framework.dart:3834:32)
#31 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6594:17)
#32 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#33 Element.updateChildren (package:flutter/src/widgets/framework.dart:3834:32)
#34 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6594:17)
#35 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#36 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#37 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
#38 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#39 StatefulElement.update (package:flutter/src/widgets/framework.dart:5485:5)
#40 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#41 Element.updateChildren (package:flutter/src/widgets/framework.dart:3834:32)
#42 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6594:17)
#43 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#44 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#45 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#46 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#47 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
#48 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#49 StatefulElement.update (package:flutter/src/widgets/framework.dart:5485:5)
#50 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#51 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#52 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#53 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#54 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#55 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#56 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#57 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#58 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#59 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#60 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#61 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#62 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
#63 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#64 StatefulElement.update (package:flutter/src/widgets/framework.dart:5485:5)
#65 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#66 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#67 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#68 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#69 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#70 ProxyElement.update (package:flutter/src/widgets/framework.dart:5628:5)
#71 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#72 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6441:14)
#73 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#74 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#75 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#76 ProxyElement.update (package:flutter/src/widgets/framework.dart:5628:5)
#77 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#78 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#79 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5462:11)
#80 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#81 StatefulElement.update (package:flutter/src/widgets/framework.dart:5485:5)
#82 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#83 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#84 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#85 ProxyElement.update (package:flutter/src/widgets/framework.dart:5628:5)
#86 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#87 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5322:16)
#88 Element.rebuild (package:flutter/src/widgets/framework.dart:5016:7)
#89 StatelessElement.update (package:flutter/src/widgets/framework.dart:5373:5)
#90 Element.updateChild (package:flutter/src/widgets/framework.dart:3685:15)
#91 _LayoutBuilderElement._layout.layoutCallback (package:flutter/src/widgets/layout_builder.dart:135:18)
#92 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2719:19)
#93 _LayoutBuilderElement._layout (package:flutter/src/widgets/layout_builder.dart:153:12)
#94 RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:2604:59)
#95 PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1059:15)
#96 RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:2604:14)
#97 RenderConstrainedLayoutBuilder.rebuildIfNecessary (package:flutter/src/widgets/layout_builder.dart:228:7)
#98 _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:313:5)
#99 RenderObject.layout (package:flutter/src/rendering/object.dart:2493:7)
#100 RenderBox.layout (package:flutter/src/rendering/box.dart:2382:11)
#101 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#102 RenderObject.layout (package:flutter/src/rendering/object.dart:2493:7)
#103 RenderBox.layout (package:flutter/src/rendering/box.dart:2382:11)
#104 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#105 RenderCustomPaint.performLayout (package:flutter/src/rendering/custom_paint.dart:554:11)
#106 RenderObject.layout (package:flutter/src/rendering/object.dart:2493:7)
#107 RenderBox.layout (package:flutter/src/rendering/box.dart:2382:11)
#108 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#109 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1431:11)
#110 RenderObject.layout (package:flutter/src/rendering/object.dart:2493:7)
#111 RenderBox.layout (package:flutter/src/rendering/box.dart:2382:11)
#112 RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#113 RenderObject.layout (package:flutter/src/rendering/object.dart:2493:7)
#114 RenderBox.layout (package:flutter/src/rendering/box.dart:2382:11)
#115 _RenderBottomSheetLayoutWithSizeListener.performLayout (package:flutter/src/material/bottom_sheet.dart:614:14)
#116 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2332:7)
#117 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1013:18)
#118 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:494:19)
#119 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:918:13)
#120 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:360:5)
#121 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1297:15)
#122 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1227:9)
#123 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1085:5)
#124 _invoke (dart:ui/hooks.dart:170:13)
#125 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:401:5)
#126 _drawFrame (dart:ui/hooks.dart:140:31)
This is the CodeSnippet of the "breakslots" with the CupertinoPicker:
Widget _buildBreakSlot(BreakSlot breakSlot) {
final error = _breakSlotErrors[breakSlot.index];
String errorMessage = '';
if (error != null) {
switch (error) {
case _BreakSlotError.overlapsWithOtherBreak:
errorMessage = AppLocalizations.of(context).timeKeepingBreakOverlaps;
break;
case _BreakSlotError.tooCloseToWorkStart:
errorMessage = AppLocalizations.of(context).timeKeepingBreakTooCloseToWorkStart;
break;
case _BreakSlotError.tooCloseToWorkEnd:
errorMessage = AppLocalizations.of(context).timeKeepingBreakTooCloseToWorkEnd;
break;
}
}
return Column(
children: [
InkWell(
onTap: () {
setState(() {
if (currentEditingBreaktimeIndex != null &&
currentEditingBreaktimeIndex == breakSlot.index &&
!editWorktime) {
currentEditingBreaktimeIndex = null;
} else {
editWorktime = false;
currentEditingBreaktimeIndex = breakSlot.index;
}
});
},
child: Ink(
child: _buildTimeHeader(
context,
'Pause',
breakSlot.startTime,
breakSlot.endTime,
currentEditingBreaktimeIndex != null && currentEditingBreaktimeIndex == breakSlot.index,
),
)),
const Divider(
height: 0.5,
),
AnimatedSize(
duration: const Duration(milliseconds: 300),
child: Container(
alignment: Alignment.centerLeft,
height: currentEditingBreaktimeIndex != null && currentEditingBreaktimeIndex == breakSlot.index
? 150.0
: 0.0001,
child: Row(
children: [
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
minuteInterval: timeSlotDurationInMinutes,
initialDateTime: breakSlot.startTime,
onDateTimeChanged: (DateTime value) {
setState(() {
//_value = _value.withStartDateTime(value);
});
//widget.onChanged(_value);
// _newValue = value;
},
use24hFormat: true,
),
),
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
minuteInterval: timeSlotDurationInMinutes,
initialDateTime: breakSlot.endTime,
onDateTimeChanged: (DateTime value) {
setState(() {
//_value = _value.withEndDateTime(value);
});
//widget.onChanged(_value);
// _newValue = value;
},
use24hFormat: true,
),
),
],
),
),
),
AnimatedSize(
duration: const Duration(milliseconds: 500),
child: Container(
alignment: Alignment.centerLeft,
height: 0.0,
child: Text(
errorMessage,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
),
)
],
);
}
And this where i show it with a list of breakSlot items:
@override
Widget build(BuildContext context) {
final breakSlots = _value.breakSlots;
return Column(
children: [
const Divider(
height: 0.5,
),
InkWell(
onTap: () {
setState(() {
if (!editWorktime) {
currentEditingBreaktimeIndex = null;
editWorktime = true;
} else {
editWorktime = false;
}
});
},
child: Ink(
child: _buildTimeHeader(context, 'Arbeitszeit', _value.startDateTime!, _value.endDateTime!, editWorktime),
),
),
const Divider(
height: 0.5,
),
AnimatedSize(
duration: const Duration(milliseconds: 300),
child: Container(
alignment: Alignment.centerLeft,
height: editWorktime ? 150.0 : 0.0001,
child: Row(
children: [
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
minuteInterval: timeSlotDurationInMinutes,
initialDateTime: _value.startDateTime ??
DateTime.now().copyWith(hour: 8, minute: 0, second: 0, millisecond: 0, microsecond: 0),
onDateTimeChanged: (DateTime value) {
setState(() {
_value = _value.withStartDateTime(value);
});
widget.onChanged(_value);
// _newValue = value;
},
use24hFormat: true,
),
),
Expanded(
child: CupertinoDatePicker(
mode: CupertinoDatePickerMode.time,
minuteInterval: timeSlotDurationInMinutes,
initialDateTime: _value.endDateTime ??
DateTime.now().copyWith(hour: 16, minute: 30, second: 0, millisecond: 0, microsecond: 0),
onDateTimeChanged: (DateTime value) {
setState(() {
_value = _value.withEndDateTime(value);
});
widget.onChanged(_value);
// _newValue = value;
},
use24hFormat: true,
),
),
],
),
),
),
for (var breakSlot in _value.breakSlots) _buildBreakSlot(breakSlot),
ListTile(
onTap: () {
widget.onChanged(_value);
setState(() {
_value = _value.addBreakSlot();
currentEditingBreaktimeIndex = _value.breakSlots.last.index;
});
},
title: Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: FaIcon(
FontAwesomeIcons.lightPlus,
size: 16.0,
color: Theme.of(context).colorScheme.secondary,
),
),
Text(
'Pause',
style: TextStyle(color: Theme.of(context).colorScheme.secondary),
),
],
)),
],
);
}
Null check is shown me in scroll_position.dart:226
/// Where the scrolling is taking place.
///
/// Typically implemented by [ScrollableState].
final ScrollContext context;
/// Save the current scroll offset with [PageStorage] and restore it if
/// this scroll position's scrollable is recreated.
///
/// See also:
///
/// * [ScrollController.keepScrollOffset] and [PageController.keepPage], which
/// create scroll positions and initialize this property.
// TODO(goderbauer): Deprecate this when state restoration supports all features of PageStorage.
final bool keepScrollOffset;
/// A label that is used in the [toString] output.
///
/// Intended to aid with identifying animation controller instances in debug
/// output.
final String? debugLabel;
@override
double get minScrollExtent => _minScrollExtent!;
double? _minScrollExtent;
@override
double get maxScrollExtent => _maxScrollExtent!;
double? _maxScrollExtent;
@override
bool get hasContentDimensions => _minScrollExtent != null && _maxScrollExtent != null;
```
I tried many things like, wrap the CupertinoDatePicker directly into a SizedBox with height or removed the AnimatedSize-Widget and some other stuff, but i have the feeling that its a bug inside of the CupertinoDatePicker in Flutter itself.