Skip to content

Commit bbdde4e

Browse files
committed
fix: Fixed dark mode not updating in AdaptiveDatePicker and AdaptiveTimePicker
1 parent 32ce841 commit bbdde4e

File tree

4 files changed

+226
-123
lines changed

4 files changed

+226
-123
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
* iOS <26 & Android: Native color properties
77
* Customizable tab bar item colors for better UI flexibility
88
* **FIX**: Fixed dynamic label updates not working in AdaptivePopupMenuItem
9-
* Added proper state management and menu item update mechanism for all platforms
9+
* Labels now properly update when state changes
10+
* **FIX**: Fixed dark mode not updating in AdaptiveDatePicker and AdaptiveTimePicker
11+
* Pickers now respond to theme changes dynamically
1012

1113
## [0.1.97]
1214
* **NEW**: Added `spacerAfter` parameter (ToolbarSpacerType) to AdaptiveAppBarAction for iOS 26+ Liquid Glass toolbar grouping

example/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ environment:
77
sdk: ^3.9.2
88
flutter: ">=1.17.0"
99

10+
1011
dependencies:
1112
go_router: ^15.1.2
1213
cupertino_icons: ^1.0.8

lib/src/widgets/adaptive_date_picker.dart

Lines changed: 114 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -55,69 +55,15 @@ class AdaptiveDatePicker {
5555
return showCupertinoModalPopup<DateTime>(
5656
context: context,
5757
builder: (BuildContext context) {
58-
return Container(
59-
height: 280,
60-
color: CupertinoColors.systemBackground.resolveFrom(context),
61-
child: Column(
62-
children: [
63-
// Header with Done button
64-
Container(
65-
padding: const EdgeInsets.symmetric(
66-
horizontal: 16,
67-
vertical: 8,
68-
),
69-
decoration: BoxDecoration(
70-
border: Border(
71-
bottom: BorderSide(
72-
color: CupertinoColors.separator.resolveFrom(context),
73-
width: 0.5,
74-
),
75-
),
76-
),
77-
child: Row(
78-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
79-
children: [
80-
CupertinoButton(
81-
padding: EdgeInsets.zero,
82-
onPressed: () => Navigator.of(context).pop(),
83-
child: Text(
84-
PlatformInfo.isIOS
85-
? CupertinoLocalizations.of(
86-
context,
87-
).cancelButtonLabel
88-
: MaterialLocalizations.of(
89-
context,
90-
).cancelButtonLabel,
91-
),
92-
),
93-
CupertinoButton(
94-
padding: EdgeInsets.zero,
95-
onPressed: () => Navigator.of(context).pop(selectedDate),
96-
child: Text(
97-
MaterialLocalizations.of(context).okButtonLabel,
98-
style: const TextStyle(fontWeight: FontWeight.w600),
99-
),
100-
),
101-
],
102-
),
103-
),
104-
// Date picker
105-
Expanded(
106-
child: CupertinoDatePicker(
107-
mode: mode,
108-
initialDateTime: initialDate,
109-
minimumDate: firstDate,
110-
maximumDate: lastDate,
111-
onDateTimeChanged: (DateTime newDate) {
112-
selectedDate = newDate;
113-
},
114-
),
115-
),
116-
],
117-
),
58+
return _CupertinoDatePickerContent(
59+
initialDate: initialDate,
60+
firstDate: firstDate,
61+
lastDate: lastDate,
62+
mode: mode,
63+
onDateSelected: (date) => selectedDate = date,
11864
);
11965
},
120-
);
66+
).then((result) => result != null ? selectedDate : null);
12167
}
12268

12369
static Future<DateTime?> _showMaterialDatePicker({
@@ -136,3 +82,110 @@ class AdaptiveDatePicker {
13682
);
13783
}
13884
}
85+
86+
/// Internal widget that properly updates when theme changes
87+
class _CupertinoDatePickerContent extends StatefulWidget {
88+
const _CupertinoDatePickerContent({
89+
required this.initialDate,
90+
required this.firstDate,
91+
required this.lastDate,
92+
required this.mode,
93+
required this.onDateSelected,
94+
});
95+
96+
final DateTime initialDate;
97+
final DateTime firstDate;
98+
final DateTime lastDate;
99+
final CupertinoDatePickerMode mode;
100+
final ValueChanged<DateTime> onDateSelected;
101+
102+
@override
103+
State<_CupertinoDatePickerContent> createState() =>
104+
_CupertinoDatePickerContentState();
105+
}
106+
107+
class _CupertinoDatePickerContentState
108+
extends State<_CupertinoDatePickerContent> {
109+
late DateTime selectedDate;
110+
111+
@override
112+
void initState() {
113+
super.initState();
114+
selectedDate = widget.initialDate;
115+
}
116+
117+
@override
118+
Widget build(BuildContext context) {
119+
// Use CupertinoTheme to get dynamic colors that update with theme changes
120+
final backgroundColor = CupertinoTheme.of(context).scaffoldBackgroundColor;
121+
final separatorColor = CupertinoDynamicColor.resolve(
122+
CupertinoColors.separator,
123+
context,
124+
);
125+
126+
return Container(
127+
height: 280,
128+
color: backgroundColor,
129+
child: Column(
130+
children: [
131+
// Header with Done button
132+
Container(
133+
padding: const EdgeInsets.symmetric(
134+
horizontal: 16,
135+
vertical: 8,
136+
),
137+
decoration: BoxDecoration(
138+
border: Border(
139+
bottom: BorderSide(
140+
color: separatorColor,
141+
width: 0.5,
142+
),
143+
),
144+
),
145+
child: Row(
146+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
147+
children: [
148+
CupertinoButton(
149+
padding: EdgeInsets.zero,
150+
onPressed: () => Navigator.of(context).pop(),
151+
child: Text(
152+
PlatformInfo.isIOS
153+
? CupertinoLocalizations.of(
154+
context,
155+
).cancelButtonLabel
156+
: MaterialLocalizations.of(
157+
context,
158+
).cancelButtonLabel,
159+
),
160+
),
161+
CupertinoButton(
162+
padding: EdgeInsets.zero,
163+
onPressed: () => Navigator.of(context).pop(true),
164+
child: Text(
165+
MaterialLocalizations.of(context).okButtonLabel,
166+
style: const TextStyle(fontWeight: FontWeight.w600),
167+
),
168+
),
169+
],
170+
),
171+
),
172+
// Date picker
173+
Expanded(
174+
child: CupertinoDatePicker(
175+
mode: widget.mode,
176+
initialDateTime: widget.initialDate,
177+
minimumDate: widget.firstDate,
178+
maximumDate: widget.lastDate,
179+
onDateTimeChanged: (DateTime newDate) {
180+
setState(() {
181+
selectedDate = newDate;
182+
});
183+
widget.onDateSelected(newDate);
184+
},
185+
),
186+
),
187+
],
188+
),
189+
);
190+
}
191+
}

lib/src/widgets/adaptive_time_picker.dart

Lines changed: 108 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -47,72 +47,16 @@ class AdaptiveTimePicker {
4747
final result = await showCupertinoModalPopup<DateTime>(
4848
context: context,
4949
builder: (BuildContext context) {
50-
return Container(
51-
height: 280,
52-
color: CupertinoColors.systemBackground.resolveFrom(context),
53-
child: Column(
54-
children: [
55-
// Header with Done button
56-
Container(
57-
padding: const EdgeInsets.symmetric(
58-
horizontal: 16,
59-
vertical: 8,
60-
),
61-
decoration: BoxDecoration(
62-
border: Border(
63-
bottom: BorderSide(
64-
color: CupertinoColors.separator.resolveFrom(context),
65-
width: 0.5,
66-
),
67-
),
68-
),
69-
child: Row(
70-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
71-
children: [
72-
CupertinoButton(
73-
padding: EdgeInsets.zero,
74-
onPressed: () => Navigator.of(context).pop(),
75-
child: Text(
76-
PlatformInfo.isIOS
77-
? CupertinoLocalizations.of(
78-
context,
79-
).cancelButtonLabel
80-
: MaterialLocalizations.of(
81-
context,
82-
).cancelButtonLabel,
83-
),
84-
),
85-
CupertinoButton(
86-
padding: EdgeInsets.zero,
87-
onPressed: () =>
88-
Navigator.of(context).pop(selectedDateTime),
89-
child: Text(
90-
MaterialLocalizations.of(context).okButtonLabel,
91-
style: const TextStyle(fontWeight: FontWeight.w600),
92-
),
93-
),
94-
],
95-
),
96-
),
97-
// Time picker
98-
Expanded(
99-
child: CupertinoDatePicker(
100-
mode: CupertinoDatePickerMode.time,
101-
use24hFormat: use24HourFormat,
102-
initialDateTime: selectedDateTime,
103-
onDateTimeChanged: (DateTime newDateTime) {
104-
selectedDateTime = newDateTime;
105-
},
106-
),
107-
),
108-
],
109-
),
50+
return _CupertinoTimePickerContent(
51+
initialDateTime: selectedDateTime,
52+
use24HourFormat: use24HourFormat,
53+
onTimeSelected: (dateTime) => selectedDateTime = dateTime,
11054
);
11155
},
11256
);
11357

11458
if (result != null) {
115-
return TimeOfDay(hour: result.hour, minute: result.minute);
59+
return TimeOfDay(hour: selectedDateTime.hour, minute: selectedDateTime.minute);
11660
}
11761
return null;
11862
}
@@ -124,3 +68,106 @@ class AdaptiveTimePicker {
12468
return showTimePicker(context: context, initialTime: initialTime);
12569
}
12670
}
71+
72+
/// Internal widget that properly updates when theme changes
73+
class _CupertinoTimePickerContent extends StatefulWidget {
74+
const _CupertinoTimePickerContent({
75+
required this.initialDateTime,
76+
required this.use24HourFormat,
77+
required this.onTimeSelected,
78+
});
79+
80+
final DateTime initialDateTime;
81+
final bool use24HourFormat;
82+
final ValueChanged<DateTime> onTimeSelected;
83+
84+
@override
85+
State<_CupertinoTimePickerContent> createState() =>
86+
_CupertinoTimePickerContentState();
87+
}
88+
89+
class _CupertinoTimePickerContentState
90+
extends State<_CupertinoTimePickerContent> {
91+
late DateTime selectedDateTime;
92+
93+
@override
94+
void initState() {
95+
super.initState();
96+
selectedDateTime = widget.initialDateTime;
97+
}
98+
99+
@override
100+
Widget build(BuildContext context) {
101+
// Use CupertinoTheme to get dynamic colors that update with theme changes
102+
final backgroundColor = CupertinoTheme.of(context).scaffoldBackgroundColor;
103+
final separatorColor = CupertinoDynamicColor.resolve(
104+
CupertinoColors.separator,
105+
context,
106+
);
107+
108+
return Container(
109+
height: 280,
110+
color: backgroundColor,
111+
child: Column(
112+
children: [
113+
// Header with Done button
114+
Container(
115+
padding: const EdgeInsets.symmetric(
116+
horizontal: 16,
117+
vertical: 8,
118+
),
119+
decoration: BoxDecoration(
120+
border: Border(
121+
bottom: BorderSide(
122+
color: separatorColor,
123+
width: 0.5,
124+
),
125+
),
126+
),
127+
child: Row(
128+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
129+
children: [
130+
CupertinoButton(
131+
padding: EdgeInsets.zero,
132+
onPressed: () => Navigator.of(context).pop(),
133+
child: Text(
134+
PlatformInfo.isIOS
135+
? CupertinoLocalizations.of(
136+
context,
137+
).cancelButtonLabel
138+
: MaterialLocalizations.of(
139+
context,
140+
).cancelButtonLabel,
141+
),
142+
),
143+
CupertinoButton(
144+
padding: EdgeInsets.zero,
145+
onPressed: () =>
146+
Navigator.of(context).pop(selectedDateTime),
147+
child: Text(
148+
MaterialLocalizations.of(context).okButtonLabel,
149+
style: const TextStyle(fontWeight: FontWeight.w600),
150+
),
151+
),
152+
],
153+
),
154+
),
155+
// Time picker
156+
Expanded(
157+
child: CupertinoDatePicker(
158+
mode: CupertinoDatePickerMode.time,
159+
use24hFormat: widget.use24HourFormat,
160+
initialDateTime: widget.initialDateTime,
161+
onDateTimeChanged: (DateTime newDateTime) {
162+
setState(() {
163+
selectedDateTime = newDateTime;
164+
});
165+
widget.onTimeSelected(newDateTime);
166+
},
167+
),
168+
),
169+
],
170+
),
171+
);
172+
}
173+
}

0 commit comments

Comments
 (0)