Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e58ee0fb
Unverified
Commit
e58ee0fb
authored
Mar 22, 2021
by
Shi-Hao Hong
Committed by
GitHub
Mar 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[State Restoration] Material DateRangePicker, adds some general state restoration tests (#78506)
parent
2977a346
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
652 additions
and
63 deletions
+652
-63
date_picker.dart
packages/flutter/lib/src/material/date_picker.dart
+287
-47
restoration_properties.dart
packages/flutter/lib/src/widgets/restoration_properties.dart
+28
-0
date_picker_test.dart
packages/flutter/test/material/date_picker_test.dart
+8
-3
date_range_picker_test.dart
packages/flutter/test/material/date_range_picker_test.dart
+194
-0
restorable_property_test.dart
packages/flutter/test/widgets/restorable_property_test.dart
+135
-13
No files found.
packages/flutter/lib/src/material/date_picker.dart
View file @
e58ee0fb
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/restoration_properties.dart
View file @
e58ee0fb
...
@@ -385,6 +385,34 @@ class RestorableDateTime extends RestorableValue<DateTime> {
...
@@ -385,6 +385,34 @@ class RestorableDateTime extends RestorableValue<DateTime> {
Object
?
toPrimitives
()
=>
value
.
millisecondsSinceEpoch
;
Object
?
toPrimitives
()
=>
value
.
millisecondsSinceEpoch
;
}
}
/// A [RestorableValue] that knows how to save and restore [DateTime] that is
/// nullable.
///
/// {@macro flutter.widgets.RestorableNum}.
class
RestorableDateTimeN
extends
RestorableValue
<
DateTime
?>
{
/// Creates a [RestorableDateTime].
///
/// {@macro flutter.widgets.RestorableNum.constructor}
RestorableDateTimeN
(
DateTime
?
defaultValue
)
:
_defaultValue
=
defaultValue
;
final
DateTime
?
_defaultValue
;
@override
DateTime
?
createDefaultValue
()
=>
_defaultValue
;
@override
void
didUpdateValue
(
DateTime
?
oldValue
)
{
assert
(
debugIsSerializableForRestoration
(
value
?.
millisecondsSinceEpoch
));
notifyListeners
();
}
@override
DateTime
?
fromPrimitives
(
Object
?
data
)
=>
data
!=
null
?
DateTime
.
fromMillisecondsSinceEpoch
(
data
as
int
)
:
null
;
@override
Object
?
toPrimitives
()
=>
value
?.
millisecondsSinceEpoch
;
}
/// A base class for creating a [RestorableProperty] that stores and restores a
/// A base class for creating a [RestorableProperty] that stores and restores a
/// [Listenable].
/// [Listenable].
///
///
...
...
packages/flutter/test/material/date_picker_test.dart
View file @
e58ee0fb
...
@@ -1162,9 +1162,14 @@ void main() {
...
@@ -1162,9 +1162,14 @@ void main() {
await
tester
.
restoreFrom
(
restorationData
);
await
tester
.
restoreFrom
(
restorationData
);
expect
(
find
.
byType
(
DatePickerDialog
),
findsOneWidget
);
expect
(
find
.
byType
(
DatePickerDialog
),
findsOneWidget
);
// Select a different date
and close the date picker
.
// Select a different date.
await
tester
.
tap
(
find
.
text
(
'30'
));
await
tester
.
tap
(
find
.
text
(
'30'
));
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// Restart after the new selection. It should remain selected.
await
tester
.
restartAndRestore
();
// Close the date picker.
await
tester
.
tap
(
find
.
text
(
'OK'
));
await
tester
.
tap
(
find
.
text
(
'OK'
));
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
...
@@ -1210,8 +1215,8 @@ void main() {
...
@@ -1210,8 +1215,8 @@ void main() {
await
tester
.
tapAt
(
const
Offset
(
10.0
,
10.0
));
await
tester
.
tapAt
(
const
Offset
(
10.0
,
10.0
));
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
// The date picker should be closed, the text value
updated to th
e
// The date picker should be closed, the text value
should be the sam
e
//
newly selected dat
e.
//
as befor
e.
expect
(
find
.
byType
(
DatePickerDialog
),
findsNothing
);
expect
(
find
.
byType
(
DatePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'25/7/2021'
),
findsOneWidget
);
expect
(
find
.
text
(
'25/7/2021'
),
findsOneWidget
);
...
...
packages/flutter/test/material/date_range_picker_test.dart
View file @
e58ee0fb
...
@@ -853,4 +853,198 @@ void main() {
...
@@ -853,4 +853,198 @@ void main() {
_testInputDecorator
(
tester
.
widget
(
borderContainers
.
last
),
border
,
Colors
.
transparent
);
_testInputDecorator
(
tester
.
widget
(
borderContainers
.
last
),
border
,
Colors
.
transparent
);
});
});
});
});
testWidgets
(
'DatePickerDialog is state restorable'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
restorationScopeId:
'app'
,
home:
_RestorableDateRangePickerDialogTestWidget
(),
),
);
// The date range picker should be closed.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'1/1/2021 to 5/1/2021'
),
findsOneWidget
);
// Open the date range picker.
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
final
TestRestorationData
restorationData
=
await
tester
.
getRestorationData
();
await
tester
.
restartAndRestore
();
// The date range picker should be open after restoring.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
// Close the date range picker.
await
tester
.
tap
(
find
.
byIcon
(
Icons
.
close
));
await
tester
.
pumpAndSettle
();
// The date range picker should be closed, the text value updated to the
// newly selected date.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'1/1/2021 to 5/1/2021'
),
findsOneWidget
);
// The date range picker should be open after restoring.
await
tester
.
restoreFrom
(
restorationData
);
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
// // Select a different date and close the date range picker.
await
tester
.
tap
(
find
.
text
(
'12'
).
first
);
await
tester
.
pumpAndSettle
();
await
tester
.
tap
(
find
.
text
(
'14'
).
first
);
await
tester
.
pumpAndSettle
();
// Restart after the new selection. It should remain selected.
await
tester
.
restartAndRestore
();
// Close the date range picker.
await
tester
.
tap
(
find
.
text
(
'SAVE'
));
await
tester
.
pumpAndSettle
();
// The date range picker should be closed, the text value updated to the
// newly selected date.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'12/1/2021 to 14/1/2021'
),
findsOneWidget
);
},
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/33615
testWidgets
(
'DateRangePickerDialog state restoration - DatePickerEntryMode'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
restorationScopeId:
'app'
,
home:
_RestorableDateRangePickerDialogTestWidget
(
datePickerEntryMode:
DatePickerEntryMode
.
calendarOnly
,
),
),
);
// The date range picker should be closed.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'1/1/2021 to 5/1/2021'
),
findsOneWidget
);
// Open the date range picker.
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
// Only in calendar mode and cannot switch out.
expect
(
find
.
byType
(
TextField
),
findsNothing
);
expect
(
find
.
byIcon
(
Icons
.
edit
),
findsNothing
);
final
TestRestorationData
restorationData
=
await
tester
.
getRestorationData
();
await
tester
.
restartAndRestore
();
// The date range picker should be open after restoring.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
// Only in calendar mode and cannot switch out.
expect
(
find
.
byType
(
TextField
),
findsNothing
);
expect
(
find
.
byIcon
(
Icons
.
edit
),
findsNothing
);
// Tap on the barrier.
await
tester
.
tap
(
find
.
byIcon
(
Icons
.
close
));
await
tester
.
pumpAndSettle
();
// The date range picker should be closed, the text value should be the same
// as before.
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsNothing
);
expect
(
find
.
text
(
'1/1/2021 to 5/1/2021'
),
findsOneWidget
);
// The date range picker should be open after restoring.
await
tester
.
restoreFrom
(
restorationData
);
expect
(
find
.
byType
(
DateRangePickerDialog
),
findsOneWidget
);
// Only in calendar mode and cannot switch out.
expect
(
find
.
byType
(
TextField
),
findsNothing
);
expect
(
find
.
byIcon
(
Icons
.
edit
),
findsNothing
);
},
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/33615
}
class
_RestorableDateRangePickerDialogTestWidget
extends
StatefulWidget
{
const
_RestorableDateRangePickerDialogTestWidget
({
Key
?
key
,
this
.
datePickerEntryMode
=
DatePickerEntryMode
.
calendar
,
})
:
super
(
key:
key
);
final
DatePickerEntryMode
datePickerEntryMode
;
@override
_RestorableDateRangePickerDialogTestWidgetState
createState
()
=>
_RestorableDateRangePickerDialogTestWidgetState
();
}
class
_RestorableDateRangePickerDialogTestWidgetState
extends
State
<
_RestorableDateRangePickerDialogTestWidget
>
with
RestorationMixin
{
@override
String
?
get
restorationId
=>
'scaffold_state'
;
final
RestorableDateTimeN
_startDate
=
RestorableDateTimeN
(
DateTime
(
2021
,
1
,
1
));
final
RestorableDateTimeN
_endDate
=
RestorableDateTimeN
(
DateTime
(
2021
,
1
,
5
));
late
final
RestorableRouteFuture
<
DateTimeRange
?>
_restorableDateRangePickerRouteFuture
=
RestorableRouteFuture
<
DateTimeRange
?>(
onComplete:
_selectDateRange
,
onPresent:
(
NavigatorState
navigator
,
Object
?
arguments
)
{
return
navigator
.
restorablePush
(
_dateRangePickerRoute
,
arguments:
<
String
,
dynamic
>{
'datePickerEntryMode'
:
widget
.
datePickerEntryMode
.
index
,
}
);
},
);
@override
void
restoreState
(
RestorationBucket
?
oldBucket
,
bool
initialRestore
)
{
registerForRestoration
(
_startDate
,
'start_date'
);
registerForRestoration
(
_endDate
,
'end_date'
);
registerForRestoration
(
_restorableDateRangePickerRouteFuture
,
'date_picker_route_future'
);
}
void
_selectDateRange
(
DateTimeRange
?
newSelectedDate
)
{
if
(
newSelectedDate
!=
null
)
{
setState
(()
{
_startDate
.
value
=
newSelectedDate
.
start
;
_endDate
.
value
=
newSelectedDate
.
end
;
});
}
}
static
Route
<
DateTimeRange
?>
_dateRangePickerRoute
(
BuildContext
context
,
Object
?
arguments
,
)
{
return
DialogRoute
<
DateTimeRange
?>(
context:
context
,
builder:
(
BuildContext
context
)
{
final
Map
<
dynamic
,
dynamic
>
args
=
arguments
!
as
Map
<
dynamic
,
dynamic
>;
return
DateRangePickerDialog
(
restorationId:
'date_picker_dialog'
,
initialEntryMode:
DatePickerEntryMode
.
values
[
args
[
'datePickerEntryMode'
]
as
int
],
firstDate:
DateTime
(
2021
,
1
,
1
),
currentDate:
DateTime
(
2021
,
1
,
25
),
lastDate:
DateTime
(
2022
,
1
,
1
),
);
},
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
DateTime
?
startDateTime
=
_startDate
.
value
;
final
DateTime
?
endDateTime
=
_endDate
.
value
;
// Example: "25/7/1994"
final
String
startDateTimeString
=
'
${startDateTime?.day}
/
${startDateTime?.month}
/
${startDateTime?.year}
'
;
final
String
endDateTimeString
=
'
${endDateTime?.day}
/
${endDateTime?.month}
/
${endDateTime?.year}
'
;
return
Scaffold
(
body:
Center
(
child:
Column
(
children:
<
Widget
>[
OutlinedButton
(
onPressed:
()
{
_restorableDateRangePickerRouteFuture
.
present
();
},
child:
const
Text
(
'X'
),
),
Text
(
'
$startDateTimeString
to
$endDateTimeString
'
),
],
),
),
);
}
}
}
packages/flutter/test/widgets/restorable_property_test.dart
View file @
e58ee0fb
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment