mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Day picker should dispose created MaterialStatesController's. (#133884)
Fixes https://github.com/flutter/flutter/issues/133862
This commit is contained in:
parent
3f4ee3fbcc
commit
5555836712
@ -868,6 +868,10 @@ class _DayPickerState extends State<_DayPicker> {
|
||||
/// List of [FocusNode]s, one for each day of the month.
|
||||
late List<FocusNode> _dayFocusNodes;
|
||||
|
||||
// TODO(polina-c): a cleaner solution is to create separate statefull widget for a day.
|
||||
// https://github.com/flutter/flutter/issues/134323
|
||||
final Map<int, MaterialStatesController> _statesControllers = <int, MaterialStatesController>{};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -893,6 +897,9 @@ class _DayPickerState extends State<_DayPicker> {
|
||||
for (final FocusNode node in _dayFocusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
for (final MaterialStatesController controller in _statesControllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -973,6 +980,9 @@ class _DayPickerState extends State<_DayPicker> {
|
||||
if (isSelectedDay) MaterialState.selected,
|
||||
};
|
||||
|
||||
final MaterialStatesController statesController = _statesControllers.putIfAbsent(day, () => MaterialStatesController());
|
||||
statesController.value = states;
|
||||
|
||||
final Color? dayForegroundColor = resolve<Color?>((DatePickerThemeData? theme) => isToday ? theme?.todayForegroundColor : theme?.dayForegroundColor, states);
|
||||
final Color? dayBackgroundColor = resolve<Color?>((DatePickerThemeData? theme) => isToday ? theme?.todayBackgroundColor : theme?.dayBackgroundColor, states);
|
||||
final MaterialStateProperty<Color?> dayOverlayColor = MaterialStateProperty.resolveWith<Color?>(
|
||||
@ -1008,7 +1018,7 @@ class _DayPickerState extends State<_DayPicker> {
|
||||
focusNode: _dayFocusNodes[day - 1],
|
||||
onTap: () => widget.onChanged(dayToBuild),
|
||||
radius: _dayPickerRowHeight / 2 + 4,
|
||||
statesController: MaterialStatesController(states),
|
||||
statesController: statesController,
|
||||
overlayColor: dayOverlayColor,
|
||||
child: Semantics(
|
||||
// We want the day of month to be spoken first irrespective of the
|
||||
|
||||
@ -516,6 +516,30 @@ void main() {
|
||||
expect(find.text('2017'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Selecting disabled date does not change current selection', (WidgetTester tester) async {
|
||||
DateTime day(int day) => DateTime(2020, DateTime.may, day);
|
||||
|
||||
DateTime selection = day(2);
|
||||
await tester.pumpWidget(calendarDatePicker(
|
||||
initialDate: selection,
|
||||
firstDate: day(2),
|
||||
lastDate: day(3),
|
||||
onDateChanged: (DateTime date) {
|
||||
selection = date;
|
||||
},
|
||||
));
|
||||
|
||||
await tester.tap(find.text('3'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(selection, day(3));
|
||||
await tester.tap(find.text('4'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(selection, day(3));
|
||||
await tester.tap(find.text('5'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(selection, day(3));
|
||||
});
|
||||
|
||||
for (final bool useMaterial3 in <bool>[false, true]) {
|
||||
testWidgets('Updates to initialDate parameter are not reflected in the state (useMaterial3=$useMaterial3)', (WidgetTester tester) async {
|
||||
final Key pickerKey = UniqueKey();
|
||||
|
||||
@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
@ -173,16 +172,11 @@ void main() {
|
||||
}, useMaterial3: theme.useMaterial3);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Material3 uses sentence case labels', (WidgetTester tester) async {
|
||||
testWidgets('Material3 uses sentence case labels', (WidgetTester tester) async {
|
||||
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||
expect(find.text('Select date'), findsOneWidget);
|
||||
}, useMaterial3: true);
|
||||
},
|
||||
leakTrackingTestConfig: const LeakTrackingTestConfig(
|
||||
// TODO(polina-c): remove after fixing
|
||||
// https://github.com/flutter/flutter/issues/133862
|
||||
allowAllNotDisposed: true,
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Cancel, confirm, and help text is used', (WidgetTester tester) async {
|
||||
cancelText = 'nope';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user