1// Copyright 2015 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. 4 5import 'dart:async'; 6 7import 'package:flutter/material.dart'; 8import 'package:intl/intl.dart'; 9 10import '../../gallery/demo.dart'; 11 12class _InputDropdown extends StatelessWidget { 13 const _InputDropdown({ 14 Key key, 15 this.child, 16 this.labelText, 17 this.valueText, 18 this.valueStyle, 19 this.onPressed, 20 }) : super(key: key); 21 22 final String labelText; 23 final String valueText; 24 final TextStyle valueStyle; 25 final VoidCallback onPressed; 26 final Widget child; 27 28 @override 29 Widget build(BuildContext context) { 30 return InkWell( 31 onTap: onPressed, 32 child: InputDecorator( 33 decoration: InputDecoration( 34 labelText: labelText, 35 ), 36 baseStyle: valueStyle, 37 child: Row( 38 mainAxisAlignment: MainAxisAlignment.spaceBetween, 39 mainAxisSize: MainAxisSize.min, 40 children: <Widget>[ 41 Text(valueText, style: valueStyle), 42 Icon(Icons.arrow_drop_down, 43 color: Theme.of(context).brightness == Brightness.light ? Colors.grey.shade700 : Colors.white70, 44 ), 45 ], 46 ), 47 ), 48 ); 49 } 50} 51 52class _DateTimePicker extends StatelessWidget { 53 const _DateTimePicker({ 54 Key key, 55 this.labelText, 56 this.selectedDate, 57 this.selectedTime, 58 this.selectDate, 59 this.selectTime, 60 }) : super(key: key); 61 62 final String labelText; 63 final DateTime selectedDate; 64 final TimeOfDay selectedTime; 65 final ValueChanged<DateTime> selectDate; 66 final ValueChanged<TimeOfDay> selectTime; 67 68 Future<void> _selectDate(BuildContext context) async { 69 final DateTime picked = await showDatePicker( 70 context: context, 71 initialDate: selectedDate, 72 firstDate: DateTime(2015, 8), 73 lastDate: DateTime(2101), 74 ); 75 if (picked != null && picked != selectedDate) 76 selectDate(picked); 77 } 78 79 Future<void> _selectTime(BuildContext context) async { 80 final TimeOfDay picked = await showTimePicker( 81 context: context, 82 initialTime: selectedTime, 83 ); 84 if (picked != null && picked != selectedTime) 85 selectTime(picked); 86 } 87 88 @override 89 Widget build(BuildContext context) { 90 final TextStyle valueStyle = Theme.of(context).textTheme.title; 91 return Row( 92 crossAxisAlignment: CrossAxisAlignment.end, 93 children: <Widget>[ 94 Expanded( 95 flex: 4, 96 child: _InputDropdown( 97 labelText: labelText, 98 valueText: DateFormat.yMMMd().format(selectedDate), 99 valueStyle: valueStyle, 100 onPressed: () { _selectDate(context); }, 101 ), 102 ), 103 const SizedBox(width: 12.0), 104 Expanded( 105 flex: 3, 106 child: _InputDropdown( 107 valueText: selectedTime.format(context), 108 valueStyle: valueStyle, 109 onPressed: () { _selectTime(context); }, 110 ), 111 ), 112 ], 113 ); 114 } 115} 116 117class DateAndTimePickerDemo extends StatefulWidget { 118 static const String routeName = '/material/date-and-time-pickers'; 119 120 @override 121 _DateAndTimePickerDemoState createState() => _DateAndTimePickerDemoState(); 122} 123 124class _DateAndTimePickerDemoState extends State<DateAndTimePickerDemo> { 125 DateTime _fromDate = DateTime.now(); 126 TimeOfDay _fromTime = const TimeOfDay(hour: 7, minute: 28); 127 DateTime _toDate = DateTime.now(); 128 TimeOfDay _toTime = const TimeOfDay(hour: 7, minute: 28); 129 final List<String> _allActivities = <String>['hiking', 'swimming', 'boating', 'fishing']; 130 String _activity = 'fishing'; 131 132 @override 133 Widget build(BuildContext context) { 134 return Scaffold( 135 appBar: AppBar( 136 title: const Text('Date and time pickers'), 137 actions: <Widget>[MaterialDemoDocumentationButton(DateAndTimePickerDemo.routeName)], 138 ), 139 body: DropdownButtonHideUnderline( 140 child: SafeArea( 141 top: false, 142 bottom: false, 143 child: ListView( 144 padding: const EdgeInsets.all(16.0), 145 children: <Widget>[ 146 TextField( 147 enabled: true, 148 decoration: const InputDecoration( 149 labelText: 'Event name', 150 border: OutlineInputBorder(), 151 ), 152 style: Theme.of(context).textTheme.display1, 153 ), 154 TextField( 155 decoration: const InputDecoration( 156 labelText: 'Location', 157 ), 158 style: Theme.of(context).textTheme.display1.copyWith(fontSize: 20.0), 159 ), 160 _DateTimePicker( 161 labelText: 'From', 162 selectedDate: _fromDate, 163 selectedTime: _fromTime, 164 selectDate: (DateTime date) { 165 setState(() { 166 _fromDate = date; 167 }); 168 }, 169 selectTime: (TimeOfDay time) { 170 setState(() { 171 _fromTime = time; 172 }); 173 }, 174 ), 175 _DateTimePicker( 176 labelText: 'To', 177 selectedDate: _toDate, 178 selectedTime: _toTime, 179 selectDate: (DateTime date) { 180 setState(() { 181 _toDate = date; 182 }); 183 }, 184 selectTime: (TimeOfDay time) { 185 setState(() { 186 _toTime = time; 187 }); 188 }, 189 ), 190 const SizedBox(height: 8.0), 191 InputDecorator( 192 decoration: const InputDecoration( 193 labelText: 'Activity', 194 hintText: 'Choose an activity', 195 contentPadding: EdgeInsets.zero, 196 ), 197 isEmpty: _activity == null, 198 child: DropdownButton<String>( 199 value: _activity, 200 onChanged: (String newValue) { 201 setState(() { 202 _activity = newValue; 203 }); 204 }, 205 items: _allActivities.map<DropdownMenuItem<String>>((String value) { 206 return DropdownMenuItem<String>( 207 value: value, 208 child: Text(value), 209 ); 210 }).toList(), 211 ), 212 ), 213 ], 214 ), 215 ), 216 ), 217 ); 218 } 219} 220