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
8ec4f229
Commit
8ec4f229
authored
Oct 03, 2016
by
Adam Barth
Committed by
GitHub
Oct 03, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add landscape time picker (#6173)
Fixes #988
parent
66127250
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
356 additions
and
325 deletions
+356
-325
material.dart
packages/flutter/lib/material.dart
+0
-1
date_picker.dart
packages/flutter/lib/src/material/date_picker.dart
+10
-8
dialog.dart
packages/flutter/lib/src/material/dialog.dart
+0
-1
time_picker.dart
packages/flutter/lib/src/material/time_picker.dart
+271
-122
time_picker_dialog.dart
packages/flutter/lib/src/material/time_picker_dialog.dart
+0
-99
time_picker_test.dart
packages/flutter/test/material/time_picker_test.dart
+75
-94
No files found.
packages/flutter/lib/material.dart
View file @
8ec4f229
...
@@ -73,7 +73,6 @@ export 'src/material/tabs.dart';
...
@@ -73,7 +73,6 @@ export 'src/material/tabs.dart';
export
'src/material/theme.dart'
;
export
'src/material/theme.dart'
;
export
'src/material/theme_data.dart'
;
export
'src/material/theme_data.dart'
;
export
'src/material/time_picker.dart'
;
export
'src/material/time_picker.dart'
;
export
'src/material/time_picker_dialog.dart'
;
export
'src/material/toggleable.dart'
;
export
'src/material/toggleable.dart'
;
export
'src/material/tooltip.dart'
;
export
'src/material/tooltip.dart'
;
export
'src/material/two_level_list.dart'
;
export
'src/material/two_level_list.dart'
;
...
...
packages/flutter/lib/src/material/date_picker.dart
View file @
8ec4f229
...
@@ -94,8 +94,8 @@ class _DatePickerHeader extends StatelessWidget {
...
@@ -94,8 +94,8 @@ class _DatePickerHeader extends StatelessWidget {
break
;
break
;
}
}
double
height
;
double
width
;
double
width
;
double
height
;
EdgeInsets
padding
;
EdgeInsets
padding
;
MainAxisAlignment
mainAxisAlignment
;
MainAxisAlignment
mainAxisAlignment
;
switch
(
orientation
)
{
switch
(
orientation
)
{
...
@@ -604,7 +604,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
...
@@ -604,7 +604,6 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
);
);
Widget
actions
=
new
ButtonTheme
.
bar
(
Widget
actions
=
new
ButtonTheme
.
bar
(
child:
new
ButtonBar
(
child:
new
ButtonBar
(
alignment:
MainAxisAlignment
.
end
,
children:
<
Widget
>[
children:
<
Widget
>[
new
FlatButton
(
new
FlatButton
(
child:
new
Text
(
'CANCEL'
),
child:
new
Text
(
'CANCEL'
),
...
@@ -646,12 +645,15 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
...
@@ -646,12 +645,15 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
children:
<
Widget
>[
header
,
header
,
new
SizedBox
(
new
Flexible
(
width:
_kMonthPickerLandscapeWidth
,
fit:
FlexFit
.
loose
,
child:
new
Column
(
child:
new
SizedBox
(
mainAxisSize:
MainAxisSize
.
min
,
width:
_kMonthPickerLandscapeWidth
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
child:
new
Column
(
children:
<
Widget
>[
picker
,
actions
]
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
picker
,
actions
]
)
)
)
)
)
]
]
...
...
packages/flutter/lib/src/material/dialog.dart
View file @
8ec4f229
...
@@ -166,7 +166,6 @@ class AlertDialog extends StatelessWidget {
...
@@ -166,7 +166,6 @@ class AlertDialog extends StatelessWidget {
if
(
actions
!=
null
)
{
if
(
actions
!=
null
)
{
children
.
add
(
new
ButtonTheme
.
bar
(
children
.
add
(
new
ButtonTheme
.
bar
(
child:
new
ButtonBar
(
child:
new
ButtonBar
(
alignment:
MainAxisAlignment
.
end
,
children:
actions
children:
actions
)
)
));
));
...
...
packages/flutter/lib/src/material/time_picker.dart
View file @
8ec4f229
...
@@ -2,13 +2,18 @@
...
@@ -2,13 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:math'
as
math
;
import
'dart:math'
as
math
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'button_bar.dart'
;
import
'button.dart'
;
import
'colors.dart'
;
import
'colors.dart'
;
import
'dialog.dart'
;
import
'flat_button.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
import
'typography.dart'
;
import
'typography.dart'
;
...
@@ -35,6 +40,18 @@ class TimeOfDay {
...
@@ -35,6 +40,18 @@ class TimeOfDay {
/// argument must be between 0 and 59, inclusive.
/// argument must be between 0 and 59, inclusive.
const
TimeOfDay
({
@required
this
.
hour
,
@required
this
.
minute
});
const
TimeOfDay
({
@required
this
.
hour
,
@required
this
.
minute
});
/// Creates a time of day based on the given time.
///
/// The [hour] is set to the time's hour and the [minute] is set to the time's
/// minute in the timezone of the given [DateTime].
TimeOfDay
.
fromDateTime
(
DateTime
time
)
:
hour
=
time
.
hour
,
minute
=
time
.
minute
;
/// Creates a time of day based on the current time.
///
/// The [hour] is set to the current hour and the [minute] is set to the
/// current minute in the local time zone.
factory
TimeOfDay
.
now
()
{
return
new
TimeOfDay
.
fromDateTime
(
new
DateTime
.
now
());
}
/// Returns a new TimeOfDay with the hour and/or minute replaced.
/// Returns a new TimeOfDay with the hour and/or minute replaced.
TimeOfDay
replacing
({
int
hour
,
int
minute
})
{
TimeOfDay
replacing
({
int
hour
,
int
minute
})
{
assert
(
hour
==
null
||
(
hour
>=
0
&&
hour
<
_kHoursPerDay
));
assert
(
hour
==
null
||
(
hour
>=
0
&&
hour
<
_kHoursPerDay
));
...
@@ -99,99 +116,33 @@ class TimeOfDay {
...
@@ -99,99 +116,33 @@ class TimeOfDay {
}
}
enum
_TimePickerMode
{
hour
,
minute
}
enum
_TimePickerMode
{
hour
,
minute
}
const
double
_kHeaderFontSize
=
60.0
;
const
double
_kPreferredDialExtent
=
296.0
;
/// A material design time picker.
const
double
_kTimePickerHeaderPortraitHeight
=
96.0
;
///
const
double
_kTimePickerHeaderLandscapeWidth
=
168.0
;
/// The time picker widget is rarely used directly. Instead, consider using
/// [showTimePicker], which creates a time picker dialog.
///
/// See also:
///
/// * [showTimePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-time-pickers>
class
TimePicker
extends
StatefulWidget
{
/// Creates a time picker.
///
/// The [selectedTime] must not be null.
///
/// Rarely used directly. Instead, consider using [showTimePicker], which
/// creates a time picker dialog.
TimePicker
({
Key
key
,
@required
this
.
selectedTime
,
@required
this
.
onChanged
})
:
super
(
key:
key
)
{
assert
(
selectedTime
!=
null
);
}
/// The currently selected time.
///
/// This time is highlighted in the picker.
final
TimeOfDay
selectedTime
;
/// Called when the user picks a time.
const
double
_kTimePickerWidthPortrait
=
328.0
;
final
ValueChanged
<
TimeOfDay
>
onChanged
;
const
double
_kTimePickerWidthLanscape
=
512.0
;
@override
const
double
_kTimePickerHeightPortrait
=
484.0
;
_TimePickerState
createState
()
=>
new
_TimePickerState
();
const
double
_kTimePickerHeightLanscape
=
304.0
;
}
class
_TimePickerState
extends
State
<
TimePicker
>
{
_TimePickerMode
_mode
=
_TimePickerMode
.
hour
;
void
_handleModeChanged
(
_TimePickerMode
mode
)
{
HapticFeedback
.
vibrate
();
setState
(()
{
_mode
=
mode
;
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
new
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
new
_TimePickerHeader
(
selectedTime:
config
.
selectedTime
,
mode:
_mode
,
onModeChanged:
_handleModeChanged
,
onChanged:
config
.
onChanged
),
new
Center
(
child:
new
Container
(
margin:
const
EdgeInsets
.
all
(
16.0
),
width:
_kPreferredDialExtent
,
child:
new
AspectRatio
(
aspectRatio:
1.0
,
child:
new
_Dial
(
mode:
_mode
,
selectedTime:
config
.
selectedTime
,
onChanged:
config
.
onChanged
)
)
)
)
]
);
}
}
// TODO(ianh): Localize!
// TODO(ianh): Localize!
class
_TimePickerHeader
extends
StatelessWidget
{
class
_TimePickerHeader
extends
StatelessWidget
{
_TimePickerHeader
({
_TimePickerHeader
({
@required
this
.
selectedTime
,
@required
this
.
selectedTime
,
@required
this
.
mode
,
@required
this
.
mode
,
@required
this
.
orientation
,
@required
this
.
onModeChanged
,
@required
this
.
onModeChanged
,
@required
this
.
onChanged
@required
this
.
onChanged
,
})
{
})
{
assert
(
selectedTime
!=
null
);
assert
(
selectedTime
!=
null
);
assert
(
mode
!=
null
);
assert
(
mode
!=
null
);
assert
(
orientation
!=
null
);
}
}
final
TimeOfDay
selectedTime
;
final
TimeOfDay
selectedTime
;
final
_TimePickerMode
mode
;
final
_TimePickerMode
mode
;
final
Orientation
orientation
;
final
ValueChanged
<
_TimePickerMode
>
onModeChanged
;
final
ValueChanged
<
_TimePickerMode
>
onModeChanged
;
final
ValueChanged
<
TimeOfDay
>
onChanged
;
final
ValueChanged
<
TimeOfDay
>
onChanged
;
...
@@ -205,10 +156,25 @@ class _TimePickerHeader extends StatelessWidget {
...
@@ -205,10 +156,25 @@ class _TimePickerHeader extends StatelessWidget {
onChanged
(
selectedTime
.
replacing
(
hour:
newHour
));
onChanged
(
selectedTime
.
replacing
(
hour:
newHour
));
}
}
TextStyle
_getBaseHeaderStyle
(
TextTheme
headerTextTheme
)
{
// These font sizes aren't listed in the spec explicitly. I worked them out
// by measuring the text using a screen ruler and comparing them to the
// screen shots of the time picker in the spec.
assert
(
orientation
!=
null
);
switch
(
orientation
)
{
case
Orientation
.
portrait
:
return
headerTextTheme
.
display3
.
copyWith
(
fontSize:
60.0
);
case
Orientation
.
landscape
:
return
headerTextTheme
.
display2
.
copyWith
(
fontSize:
50.0
);
}
return
null
;
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
ThemeData
themeData
=
Theme
.
of
(
context
);
ThemeData
themeData
=
Theme
.
of
(
context
);
TextTheme
headerTextTheme
=
themeData
.
primaryTextTheme
;
TextTheme
headerTextTheme
=
themeData
.
primaryTextTheme
;
TextStyle
baseHeaderStyle
=
_getBaseHeaderStyle
(
headerTextTheme
);
Color
activeColor
;
Color
activeColor
;
Color
inactiveColor
;
Color
inactiveColor
;
switch
(
themeData
.
primaryColorBrightness
)
{
switch
(
themeData
.
primaryColorBrightness
)
{
...
@@ -232,12 +198,8 @@ class _TimePickerHeader extends StatelessWidget {
...
@@ -232,12 +198,8 @@ class _TimePickerHeader extends StatelessWidget {
break
;
break
;
}
}
TextStyle
activeStyle
=
headerTextTheme
.
display3
.
copyWith
(
TextStyle
activeStyle
=
baseHeaderStyle
.
copyWith
(
color:
activeColor
);
fontSize:
_kHeaderFontSize
,
color:
activeColor
TextStyle
inactiveStyle
=
baseHeaderStyle
.
copyWith
(
color:
inactiveColor
);
);
TextStyle
inactiveStyle
=
headerTextTheme
.
display3
.
copyWith
(
fontSize:
_kHeaderFontSize
,
color:
inactiveColor
);
TextStyle
hourStyle
=
mode
==
_TimePickerMode
.
hour
?
activeStyle
:
inactiveStyle
;
TextStyle
hourStyle
=
mode
==
_TimePickerMode
.
hour
?
activeStyle
:
inactiveStyle
;
TextStyle
minuteStyle
=
mode
==
_TimePickerMode
.
minute
?
activeStyle
:
inactiveStyle
;
TextStyle
minuteStyle
=
mode
==
_TimePickerMode
.
minute
?
activeStyle
:
inactiveStyle
;
...
@@ -249,50 +211,77 @@ class _TimePickerHeader extends StatelessWidget {
...
@@ -249,50 +211,77 @@ class _TimePickerHeader extends StatelessWidget {
color:
selectedTime
.
period
==
DayPeriod
.
pm
?
activeColor:
inactiveColor
color:
selectedTime
.
period
==
DayPeriod
.
pm
?
activeColor:
inactiveColor
);
);
return
new
Container
(
Widget
dayPeriodPicker
=
new
GestureDetector
(
height:
96.0
,
onTap:
_handleChangeDayPeriod
,
decoration:
new
BoxDecoration
(
backgroundColor:
backgroundColor
),
behavior:
HitTestBehavior
.
opaque
,
child:
new
Row
(
child:
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
children:
<
Widget
>[
new
Flexible
(
new
Text
(
'AM'
,
style:
amStyle
),
child:
new
Align
(
const
SizedBox
(
width:
0.0
,
height:
4.0
),
// Vertical spacer
alignment:
FractionalOffset
.
centerRight
,
new
Text
(
'PM'
,
style:
pmStyle
),
child:
new
GestureDetector
(
onTap:
()
=>
_handleChangeMode
(
_TimePickerMode
.
hour
),
child:
new
Text
(
selectedTime
.
hourOfPeriodLabel
,
style:
hourStyle
)
)
)
),
new
Text
(
':'
,
style:
inactiveStyle
),
new
Flexible
(
child:
new
Align
(
alignment:
FractionalOffset
.
centerLeft
,
child:
new
Row
(
children:
<
Widget
>[
new
GestureDetector
(
onTap:
()
=>
_handleChangeMode
(
_TimePickerMode
.
minute
),
child:
new
Text
(
selectedTime
.
minuteLabel
,
style:
minuteStyle
)
),
new
Container
(
width:
8.0
,
height:
0.0
),
// Horizontal spacer
new
GestureDetector
(
onTap:
_handleChangeDayPeriod
,
behavior:
HitTestBehavior
.
opaque
,
child:
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
new
Text
(
'AM'
,
style:
amStyle
),
new
Container
(
width:
0.0
,
height:
8.0
),
// Vertical spacer
new
Text
(
'PM'
,
style:
pmStyle
),
]
)
)
]
)
)
)
]
]
)
)
);
);
Widget
hour
=
new
Align
(
alignment:
FractionalOffset
.
centerRight
,
child:
new
GestureDetector
(
onTap:
()
=>
_handleChangeMode
(
_TimePickerMode
.
hour
),
child:
new
Text
(
selectedTime
.
hourOfPeriodLabel
,
style:
hourStyle
),
)
);
Widget
minute
=
new
GestureDetector
(
onTap:
()
=>
_handleChangeMode
(
_TimePickerMode
.
minute
),
child:
new
Text
(
selectedTime
.
minuteLabel
,
style:
minuteStyle
),
);
assert
(
orientation
!=
null
);
switch
(
orientation
)
{
case
Orientation
.
portrait
:
return
new
Container
(
height:
_kTimePickerHeaderPortraitHeight
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
24.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
backgroundColor
),
child:
new
Row
(
children:
<
Widget
>[
new
Flexible
(
child:
hour
),
new
Text
(
':'
,
style:
inactiveStyle
),
new
Flexible
(
child:
new
Row
(
children:
<
Widget
>[
minute
,
const
SizedBox
(
width:
8.0
,
height:
0.0
),
// Horizontal spacer
dayPeriodPicker
,
]
)
)
]
)
);
case
Orientation
.
landscape
:
return
new
Container
(
width:
_kTimePickerHeaderLandscapeWidth
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
backgroundColor
),
child:
new
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
new
Row
(
children:
<
Widget
>[
new
Flexible
(
child:
hour
),
new
Text
(
':'
,
style:
inactiveStyle
),
new
Flexible
(
child:
minute
),
],
),
const
SizedBox
(
width:
0.0
,
height:
8.0
),
// Vertical spacer
dayPeriodPicker
,
]
)
);
}
return
null
;
}
}
}
}
...
@@ -578,6 +567,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
...
@@ -578,6 +567,7 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
onPanUpdate:
_handlePanUpdate
,
onPanUpdate:
_handlePanUpdate
,
onPanEnd:
_handlePanEnd
,
onPanEnd:
_handlePanEnd
,
child:
new
CustomPaint
(
child:
new
CustomPaint
(
key:
const
ValueKey
<
String
>(
'time-picker-dial'
),
// used for testing.
painter:
new
_DialPainter
(
painter:
new
_DialPainter
(
primaryLabels:
primaryLabels
,
primaryLabels:
primaryLabels
,
secondaryLabels:
secondaryLabels
,
secondaryLabels:
secondaryLabels
,
...
@@ -589,3 +579,162 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
...
@@ -589,3 +579,162 @@ class _DialState extends State<_Dial> with SingleTickerProviderStateMixin {
);
);
}
}
}
}
class
_TimePickerDialog
extends
StatefulWidget
{
_TimePickerDialog
({
Key
key
,
this
.
initialTime
})
:
super
(
key:
key
)
{
assert
(
initialTime
!=
null
);
}
final
TimeOfDay
initialTime
;
@override
_TimePickerDialogState
createState
()
=>
new
_TimePickerDialogState
();
}
class
_TimePickerDialogState
extends
State
<
_TimePickerDialog
>
{
@override
void
initState
()
{
super
.
initState
();
_selectedTime
=
config
.
initialTime
;
}
_TimePickerMode
_mode
=
_TimePickerMode
.
hour
;
TimeOfDay
_selectedTime
;
void
_handleModeChanged
(
_TimePickerMode
mode
)
{
HapticFeedback
.
vibrate
();
setState
(()
{
_mode
=
mode
;
});
}
void
_handleTimeChanged
(
TimeOfDay
value
)
{
setState
(()
{
_selectedTime
=
value
;
});
}
void
_handleCancel
()
{
Navigator
.
pop
(
context
);
}
void
_handleOk
()
{
Navigator
.
pop
(
context
,
_selectedTime
);
}
@override
Widget
build
(
BuildContext
context
)
{
Widget
picker
=
new
Padding
(
padding:
const
EdgeInsets
.
all
(
16.0
),
child:
new
AspectRatio
(
aspectRatio:
1.0
,
child:
new
_Dial
(
mode:
_mode
,
selectedTime:
_selectedTime
,
onChanged:
_handleTimeChanged
,
)
)
);
Widget
actions
=
new
ButtonTheme
.
bar
(
child:
new
ButtonBar
(
children:
<
Widget
>[
new
FlatButton
(
child:
new
Text
(
'CANCEL'
),
onPressed:
_handleCancel
),
new
FlatButton
(
child:
new
Text
(
'OK'
),
onPressed:
_handleOk
),
]
)
);
return
new
Dialog
(
child:
new
OrientationBuilder
(
builder:
(
BuildContext
context
,
Orientation
orientation
)
{
Widget
header
=
new
_TimePickerHeader
(
selectedTime:
_selectedTime
,
mode:
_mode
,
orientation:
orientation
,
onModeChanged:
_handleModeChanged
,
onChanged:
_handleTimeChanged
,
);
assert
(
orientation
!=
null
);
switch
(
orientation
)
{
case
Orientation
.
portrait
:
return
new
SizedBox
(
width:
_kTimePickerWidthPortrait
,
height:
_kTimePickerHeightPortrait
,
child:
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
header
,
new
Flexible
(
child:
picker
),
actions
,
]
)
);
case
Orientation
.
landscape
:
return
new
SizedBox
(
width:
_kTimePickerWidthLanscape
,
height:
_kTimePickerHeightLanscape
,
child:
new
Row
(
mainAxisSize:
MainAxisSize
.
min
,
crossAxisAlignment:
CrossAxisAlignment
.
stretch
,
children:
<
Widget
>[
header
,
new
Flexible
(
fit:
FlexFit
.
loose
,
child:
new
Column
(
children:
<
Widget
>[
new
Flexible
(
child:
picker
),
actions
,
]
)
),
]
)
);
}
return
null
;
}
)
);
}
}
/// Shows a dialog containing a material design time picker.
///
/// The returned Future resolves to the time selected by the user when the user
/// closes the dialog. If the user cancels the dialog, the Future resolves to
/// the [initialTime].
///
/// To show a dialog with [initialTime] equal to the current time:
/// ```dart
/// showTimePicker(
/// initialTime: new TimeOfDay.now(),
/// context: context
/// );
/// ```
///
/// See also:
///
/// * [showDatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-time-pickers>
Future
<
TimeOfDay
>
showTimePicker
({
BuildContext
context
,
TimeOfDay
initialTime
})
async
{
assert
(
initialTime
!=
null
);
return
await
showDialog
(
context:
context
,
child:
new
_TimePickerDialog
(
initialTime:
initialTime
)
)
??
initialTime
;
}
packages/flutter/lib/src/material/time_picker_dialog.dart
deleted
100644 → 0
View file @
66127250
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter/widgets.dart'
;
import
'dialog.dart'
;
import
'time_picker.dart'
;
import
'flat_button.dart'
;
class
_TimePickerDialog
extends
StatefulWidget
{
_TimePickerDialog
({
Key
key
,
this
.
initialTime
})
:
super
(
key:
key
);
final
TimeOfDay
initialTime
;
@override
_TimePickerDialogState
createState
()
=>
new
_TimePickerDialogState
();
}
class
_TimePickerDialogState
extends
State
<
_TimePickerDialog
>
{
@override
void
initState
()
{
super
.
initState
();
_selectedTime
=
config
.
initialTime
;
}
TimeOfDay
_selectedTime
;
void
_handleTimeChanged
(
TimeOfDay
value
)
{
setState
(()
{
_selectedTime
=
value
;
});
}
void
_handleCancel
()
{
Navigator
.
pop
(
context
);
}
void
_handleOk
()
{
Navigator
.
pop
(
context
,
_selectedTime
);
}
@override
Widget
build
(
BuildContext
context
)
{
// TODO(abarth): Use Dialog directly.
return
new
AlertDialog
(
content:
new
TimePicker
(
selectedTime:
_selectedTime
,
onChanged:
_handleTimeChanged
),
contentPadding:
EdgeInsets
.
zero
,
actions:
<
Widget
>[
new
FlatButton
(
child:
new
Text
(
'CANCEL'
),
onPressed:
_handleCancel
),
new
FlatButton
(
child:
new
Text
(
'OK'
),
onPressed:
_handleOk
),
]
);
}
}
/// Shows a dialog containing a material design time picker.
///
/// The returned Future resolves to the time selected by the user when the user
/// closes the dialog. If the user cancels the dialog, the Future resolves to
/// the [initialTime].
///
/// To show a dialog with [initialTime] equal to the current time:
/// ```dart
/// final DateTime now = new DateTime.now();
/// showTimePicker(
/// initialTime: new TimeOfDay(hour: now.hour, minute: now.minute),
/// context: context
/// );
/// ```
///
/// See also:
///
/// * [TimePicker]
/// * [showDatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-time-pickers>
Future
<
TimeOfDay
>
showTimePicker
({
BuildContext
context
,
TimeOfDay
initialTime
})
async
{
return
await
showDialog
(
context:
context
,
child:
new
_TimePickerDialog
(
initialTime:
initialTime
)
)
??
initialTime
;
}
packages/flutter/test/material/time_picker_test.dart
View file @
8ec4f229
...
@@ -5,100 +5,82 @@
...
@@ -5,100 +5,82 @@
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
class
_TimePickerLauncher
extends
StatelessWidget
{
testWidgets
(
'tap-select an hour'
,
(
WidgetTester
tester
)
async
{
_TimePickerLauncher
({
Key
key
,
this
.
onChanged
})
:
super
(
key:
key
);
Key
_timePickerKey
=
new
UniqueKey
();
TimeOfDay
_selectedTime
=
const
TimeOfDay
(
hour:
7
,
minute:
0
);
final
ValueChanged
<
TimeOfDay
>
onChanged
;
await
tester
.
pumpWidget
(
@override
new
StatefulBuilder
(
Widget
build
(
BuildContext
context
)
{
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
new
MaterialApp
(
return
new
Material
(
home:
new
Material
(
child:
new
Center
(
child:
new
Center
(
child:
new
SizedBox
(
child:
new
Builder
(
width:
200.0
,
builder:
(
BuildContext
context
)
{
height:
400.0
,
return
new
RaisedButton
(
child:
new
TimePicker
(
child:
new
Text
(
'X'
),
key:
_timePickerKey
,
onPressed:
()
async
{
selectedTime:
_selectedTime
,
onChanged
(
await
showTimePicker
(
onChanged:
(
TimeOfDay
value
)
{
context:
context
,
setState
(()
{
initialTime:
const
TimeOfDay
(
hour:
7
,
minute:
0
)
_selectedTime
=
value
;
));
});
}
}
);
)
}
)
)
)
)
);
}
)
)
);
);
}
}
Point
center
=
tester
.
getCenter
(
find
.
byKey
(
_timePickerKey
));
Future
<
Point
>
startPicker
(
WidgetTester
tester
,
ValueChanged
<
TimeOfDay
>
onChanged
)
async
{
await
tester
.
pumpWidget
(
new
_TimePickerLauncher
(
onChanged:
onChanged
));
await
tester
.
tap
(
find
.
text
(
'X'
));
Point
hour0
=
new
Point
(
center
.
x
,
center
.
y
-
50.0
);
// 12:00 AM
await
tester
.
pump
();
// start animation
await
tester
.
tapAt
(
hour0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
_selectedTime
.
hour
,
equals
(
0
));
Point
hour3
=
new
Point
(
center
.
x
+
50.0
,
center
.
y
);
return
tester
.
getCenter
(
find
.
byKey
(
new
Key
(
'time-picker-dial'
)));
await
tester
.
tapAt
(
hour3
);
}
expect
(
_selectedTime
.
hour
,
equals
(
3
));
Point
hour6
=
new
Point
(
center
.
x
,
center
.
y
+
50.0
);
await
tester
.
tapAt
(
hour6
);
expect
(
_selectedTime
.
hour
,
equals
(
6
));
Point
hour9
=
new
Point
(
center
.
x
-
50.0
,
center
.
y
);
Future
<
Null
>
finishPicker
(
WidgetTester
tester
)
async
{
await
tester
.
tapAt
(
hour9
);
await
tester
.
tap
(
find
.
text
(
'OK'
));
expect
(
_selectedTime
.
hour
,
equals
(
9
));
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Finish gesture animation.
await
tester
.
pump
();
// start animation
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Finish settling animation.
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
});
}
testWidgets
(
'render picker with intrinsic dimensions'
,
(
WidgetTester
tester
)
async
{
void
main
(
)
{
await
tester
.
pumpWidget
(
testWidgets
(
'tap-select an hour'
,
(
WidgetTester
tester
)
async
{
new
IntrinsicWidth
(
TimeOfDay
result
;
child:
new
IntrinsicHeight
(
child:
new
TimePicker
(
Point
center
=
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
});
onChanged:
null
,
await
tester
.
tapAt
(
new
Point
(
center
.
x
,
center
.
y
-
50.0
));
// 12:00 AM
selectedTime:
new
TimeOfDay
(
hour:
0
,
minute:
0
)
await
finishPicker
(
tester
);
)
expect
(
result
,
equals
(
const
TimeOfDay
(
hour:
0
,
minute:
0
)));
)
)
center
=
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
});
);
await
tester
.
tapAt
(
new
Point
(
center
.
x
+
50.0
,
center
.
y
));
await
tester
.
pump
(
const
Duration
(
seconds:
5
));
await
finishPicker
(
tester
);
expect
(
result
,
equals
(
const
TimeOfDay
(
hour:
3
,
minute:
0
)));
center
=
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
});
await
tester
.
tapAt
(
new
Point
(
center
.
x
,
center
.
y
+
50.0
));
await
finishPicker
(
tester
);
expect
(
result
,
equals
(
const
TimeOfDay
(
hour:
6
,
minute:
0
)));
center
=
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
});
await
tester
.
tapAt
(
new
Point
(
center
.
x
,
center
.
y
+
50.0
));
await
tester
.
tapAt
(
new
Point
(
center
.
x
-
50
,
center
.
y
));
await
finishPicker
(
tester
);
expect
(
result
,
equals
(
const
TimeOfDay
(
hour:
9
,
minute:
0
)));
});
});
testWidgets
(
'drag-select an hour'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'drag-select an hour'
,
(
WidgetTester
tester
)
async
{
Key
_timePickerKey
=
new
UniqueKey
();
TimeOfDay
result
;
TimeOfDay
_selectedTime
=
const
TimeOfDay
(
hour:
7
,
minute:
0
);
await
tester
.
pumpWidget
(
new
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
new
Material
(
child:
new
Center
(
child:
new
SizedBox
(
width:
200.0
,
height:
400.0
,
child:
new
TimePicker
(
key:
_timePickerKey
,
selectedTime:
_selectedTime
,
onChanged:
(
TimeOfDay
value
)
{
setState
(()
{
_selectedTime
=
value
;
});
}
)
)
)
);
}
)
);
Point
center
=
tester
.
getCenter
(
find
.
byKey
(
_timePickerKey
)
);
Point
center
=
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
}
);
Point
hour0
=
new
Point
(
center
.
x
,
center
.
y
-
50.0
);
// 12:00 AM
Point
hour0
=
new
Point
(
center
.
x
,
center
.
y
-
50.0
);
// 12:00 AM
Point
hour3
=
new
Point
(
center
.
x
+
50.0
,
center
.
y
);
Point
hour3
=
new
Point
(
center
.
x
+
50.0
,
center
.
y
);
Point
hour6
=
new
Point
(
center
.
x
,
center
.
y
+
50.0
);
Point
hour6
=
new
Point
(
center
.
x
,
center
.
y
+
50.0
);
...
@@ -109,29 +91,28 @@ void main() {
...
@@ -109,29 +91,28 @@ void main() {
gesture
=
await
tester
.
startGesture
(
hour3
);
gesture
=
await
tester
.
startGesture
(
hour3
);
await
gesture
.
moveBy
(
hour0
-
hour3
);
await
gesture
.
moveBy
(
hour0
-
hour3
);
await
gesture
.
up
();
await
gesture
.
up
();
expect
(
_selectedTime
.
hour
,
equals
(
0
));
await
finishPicker
(
tester
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Finish gesture animation.
expect
(
result
.
hour
,
0
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
// Finish settling animation.
expect
(
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
}),
equals
(
center
));
gesture
=
await
tester
.
startGesture
(
hour0
);
gesture
=
await
tester
.
startGesture
(
hour0
);
await
gesture
.
moveBy
(
hour3
-
hour0
);
await
gesture
.
moveBy
(
hour3
-
hour0
);
await
gesture
.
up
();
await
gesture
.
up
();
expect
(
_selectedTime
.
hour
,
equals
(
3
));
await
finishPicker
(
tester
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
result
.
hour
,
3
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
}),
equals
(
center
));
gesture
=
await
tester
.
startGesture
(
hour3
);
gesture
=
await
tester
.
startGesture
(
hour3
);
await
gesture
.
moveBy
(
hour6
-
hour3
);
await
gesture
.
moveBy
(
hour6
-
hour3
);
await
gesture
.
up
();
await
gesture
.
up
();
expect
(
_selectedTime
.
hour
,
equals
(
6
));
await
finishPicker
(
tester
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
result
.
hour
,
equals
(
6
));
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
await
startPicker
(
tester
,
(
TimeOfDay
time
)
{
result
=
time
;
}),
equals
(
center
));
gesture
=
await
tester
.
startGesture
(
hour6
);
gesture
=
await
tester
.
startGesture
(
hour6
);
await
gesture
.
moveBy
(
hour9
-
hour6
);
await
gesture
.
moveBy
(
hour9
-
hour6
);
await
gesture
.
up
();
await
gesture
.
up
();
expect
(
_selectedTime
.
hour
,
equals
(
9
));
await
finishPicker
(
tester
);
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
expect
(
result
.
hour
,
equals
(
9
));
await
tester
.
pump
(
const
Duration
(
seconds:
1
));
});
});
}
}
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