• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4import 'package:flutter/cupertino.dart';
5import 'package:intl/intl.dart';
6
7import '../../gallery/demo.dart';
8import 'cupertino_navigation_demo.dart' show coolColorNames;
9
10const double _kPickerSheetHeight = 216.0;
11const double _kPickerItemHeight = 32.0;
12
13class CupertinoPickerDemo extends StatefulWidget {
14  static const String routeName = '/cupertino/picker';
15
16  @override
17  _CupertinoPickerDemoState createState() => _CupertinoPickerDemoState();
18}
19
20class _CupertinoPickerDemoState extends State<CupertinoPickerDemo> {
21  int _selectedColorIndex = 0;
22
23  Duration timer = const Duration();
24
25  // Value that is shown in the date picker in date mode.
26  DateTime date = DateTime.now();
27
28  // Value that is shown in the date picker in time mode.
29  DateTime time = DateTime.now();
30
31  // Value that is shown in the date picker in dateAndTime mode.
32  DateTime dateTime = DateTime.now();
33
34  Widget _buildMenu(List<Widget> children) {
35    return Container(
36      decoration: BoxDecoration(
37        color: CupertinoTheme.of(context).scaffoldBackgroundColor,
38        border: const Border(
39          top: BorderSide(color: Color(0xFFBCBBC1), width: 0.0),
40          bottom: BorderSide(color: Color(0xFFBCBBC1), width: 0.0),
41        ),
42      ),
43      height: 44.0,
44      child: Padding(
45        padding: const EdgeInsets.symmetric(horizontal: 16.0),
46        child: SafeArea(
47          top: false,
48          bottom: false,
49          child: Row(
50            mainAxisAlignment: MainAxisAlignment.spaceBetween,
51            children: children,
52          ),
53        ),
54      ),
55    );
56  }
57
58  Widget _buildBottomPicker(Widget picker) {
59    return Container(
60      height: _kPickerSheetHeight,
61      padding: const EdgeInsets.only(top: 6.0),
62      color: CupertinoColors.white,
63      child: DefaultTextStyle(
64        style: const TextStyle(
65          color: CupertinoColors.black,
66          fontSize: 22.0,
67        ),
68        child: GestureDetector(
69          // Blocks taps from propagating to the modal sheet and popping.
70          onTap: () { },
71          child: SafeArea(
72            top: false,
73            child: picker,
74          ),
75        ),
76      ),
77    );
78  }
79
80  Widget _buildColorPicker(BuildContext context) {
81    final FixedExtentScrollController scrollController =
82        FixedExtentScrollController(initialItem: _selectedColorIndex);
83
84    return GestureDetector(
85      onTap: () async {
86        await showCupertinoModalPopup<void>(
87          context: context,
88          builder: (BuildContext context) {
89            return _buildBottomPicker(
90              CupertinoPicker(
91                scrollController: scrollController,
92                itemExtent: _kPickerItemHeight,
93                backgroundColor: CupertinoColors.white,
94                onSelectedItemChanged: (int index) {
95                  setState(() => _selectedColorIndex = index);
96                },
97                children: List<Widget>.generate(coolColorNames.length, (int index) {
98                  return Center(
99                    child: Text(coolColorNames[index]),
100                  );
101                }),
102              ),
103            );
104          },
105        );
106      },
107      child: _buildMenu(
108        <Widget>[
109          const Text('Favorite Color'),
110          Text(
111            coolColorNames[_selectedColorIndex],
112            style: const TextStyle(
113                color: CupertinoColors.inactiveGray
114            ),
115          ),
116        ],
117      ),
118    );
119  }
120
121  Widget _buildCountdownTimerPicker(BuildContext context) {
122    return GestureDetector(
123      onTap: () {
124        showCupertinoModalPopup<void>(
125          context: context,
126          builder: (BuildContext context) {
127            return _buildBottomPicker(
128              CupertinoTimerPicker(
129                initialTimerDuration: timer,
130                onTimerDurationChanged: (Duration newTimer) {
131                  setState(() => timer = newTimer);
132                },
133              ),
134            );
135          },
136        );
137      },
138      child: _buildMenu(
139        <Widget>[
140          const Text('Countdown Timer'),
141          Text(
142            '${timer.inHours}:'
143                '${(timer.inMinutes % 60).toString().padLeft(2,'0')}:'
144                '${(timer.inSeconds % 60).toString().padLeft(2,'0')}',
145            style: const TextStyle(color: CupertinoColors.inactiveGray),
146          ),
147        ],
148      ),
149    );
150  }
151
152  Widget _buildDatePicker(BuildContext context) {
153    return GestureDetector(
154      onTap: () {
155        showCupertinoModalPopup<void>(
156          context: context,
157          builder: (BuildContext context) {
158            return _buildBottomPicker(
159              CupertinoDatePicker(
160                mode: CupertinoDatePickerMode.date,
161                initialDateTime: date,
162                onDateTimeChanged: (DateTime newDateTime) {
163                  setState(() => date = newDateTime);
164                },
165              ),
166            );
167          },
168        );
169      },
170      child: _buildMenu(
171        <Widget>[
172          const Text('Date'),
173          Text(
174            DateFormat.yMMMMd().format(date),
175            style: const TextStyle(color: CupertinoColors.inactiveGray),
176          ),
177        ]
178      ),
179    );
180  }
181
182  Widget _buildTimePicker(BuildContext context) {
183    return GestureDetector(
184      onTap: () {
185        showCupertinoModalPopup<void>(
186          context: context,
187          builder: (BuildContext context) {
188            return _buildBottomPicker(
189              CupertinoDatePicker(
190                mode: CupertinoDatePickerMode.time,
191                initialDateTime: time,
192                onDateTimeChanged: (DateTime newDateTime) {
193                  setState(() => time = newDateTime);
194                },
195              ),
196            );
197          },
198        );
199      },
200      child: _buildMenu(
201        <Widget>[
202          const Text('Time'),
203          Text(
204            DateFormat.jm().format(time),
205            style: const TextStyle(color: CupertinoColors.inactiveGray),
206          ),
207        ],
208      ),
209    );
210  }
211
212  Widget _buildDateAndTimePicker(BuildContext context) {
213    return GestureDetector(
214      onTap: () {
215        showCupertinoModalPopup<void>(
216          context: context,
217          builder: (BuildContext context) {
218            return _buildBottomPicker(
219              CupertinoDatePicker(
220                mode: CupertinoDatePickerMode.dateAndTime,
221                initialDateTime: dateTime,
222                onDateTimeChanged: (DateTime newDateTime) {
223                  setState(() => dateTime = newDateTime);
224                },
225              ),
226            );
227          },
228        );
229      },
230      child: _buildMenu(
231        <Widget>[
232          const Text('Date and Time'),
233          Text(
234            DateFormat.yMMMd().add_jm().format(dateTime),
235            style: const TextStyle(color: CupertinoColors.inactiveGray),
236          ),
237        ],
238      ),
239    );
240  }
241
242  @override
243  Widget build(BuildContext context) {
244    return CupertinoPageScaffold(
245      navigationBar: CupertinoNavigationBar(
246        middle: const Text('Picker'),
247        // We're specifying a back label here because the previous page is a
248        // Material page. CupertinoPageRoutes could auto-populate these back
249        // labels.
250        previousPageTitle: 'Cupertino',
251        trailing: CupertinoDemoDocumentationButton(CupertinoPickerDemo.routeName),
252      ),
253      child: DefaultTextStyle(
254        style: CupertinoTheme.of(context).textTheme.textStyle,
255        child: DecoratedBox(
256          decoration: BoxDecoration(
257            color: CupertinoTheme.of(context).brightness == Brightness.light
258                ? CupertinoColors.extraLightBackgroundGray
259                : CupertinoColors.darkBackgroundGray,
260          ),
261          child: ListView(
262            children: <Widget>[
263              const Padding(padding: EdgeInsets.only(top: 32.0)),
264              _buildColorPicker(context),
265              _buildCountdownTimerPicker(context),
266              _buildDatePicker(context),
267              _buildTimePicker(context),
268              _buildDateAndTimePicker(context),
269            ],
270          ),
271        ),
272      ),
273    );
274  }
275}
276