full_screen_dialog_demo.dart 7.75 KB
Newer Older
Hans Muller's avatar
Hans Muller committed
1 2 3 4
// Copyright 2016 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.

5 6
import 'dart:async';

7
import 'package:flutter/foundation.dart';
Hans Muller's avatar
Hans Muller committed
8
import 'package:flutter/material.dart';
9
import 'package:intl/intl.dart';
Hans Muller's avatar
Hans Muller committed
10 11

// This demo is based on
12
// https://material.google.com/components/dialogs.html#dialogs-full-screen-dialogs
Hans Muller's avatar
Hans Muller committed
13 14 15 16 17 18 19

enum DismissDialogAction {
  cancel,
  discard,
  save,
}

20
class DateTimeItem extends StatelessWidget {
21
  DateTimeItem({ Key key, DateTime dateTime, @required this.onChanged })
22 23
    : assert(onChanged != null),
      date = new DateTime(dateTime.year, dateTime.month, dateTime.day),
Hans Muller's avatar
Hans Muller committed
24
      time = new TimeOfDay(hour: dateTime.hour, minute: dateTime.minute),
25
      super(key: key);
Hans Muller's avatar
Hans Muller committed
26 27 28 29 30

  final DateTime date;
  final TimeOfDay time;
  final ValueChanged<DateTime> onChanged;

31
  @override
Hans Muller's avatar
Hans Muller committed
32 33 34
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);

35
    return new DefaultTextStyle(
36
      style: theme.textTheme.subhead,
Hans Muller's avatar
Hans Muller committed
37 38
      child: new Row(
        children: <Widget>[
39
          new Expanded(
Hans Muller's avatar
Hans Muller committed
40
            child: new Container(
41
              padding: const EdgeInsets.symmetric(vertical: 8.0),
Hans Muller's avatar
Hans Muller committed
42 43 44 45 46 47 48 49 50 51 52
              decoration: new BoxDecoration(
                border: new Border(bottom: new BorderSide(color: theme.dividerColor))
              ),
              child: new InkWell(
                onTap: () {
                  showDatePicker(
                    context: context,
                    initialDate: date,
                    firstDate: date.subtract(const Duration(days: 30)),
                    lastDate: date.add(const Duration(days: 30))
                  )
53
                  .then<Null>((DateTime value) {
Hans Muller's avatar
Hans Muller committed
54 55 56 57
                    onChanged(new DateTime(value.year, value.month, value.day, time.hour, time.minute));
                  });
                },
                child: new Row(
58
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
Hans Muller's avatar
Hans Muller committed
59 60
                  children: <Widget>[
                    new Text(new DateFormat('EEE, MMM d yyyy').format(date)),
61
                    const Icon(Icons.arrow_drop_down, color: Colors.black54),
Hans Muller's avatar
Hans Muller committed
62 63 64 65 66 67
                  ]
                )
              )
            )
          ),
          new Container(
68 69
            margin: const EdgeInsets.only(left: 8.0),
            padding: const EdgeInsets.symmetric(vertical: 8.0),
Hans Muller's avatar
Hans Muller committed
70 71 72 73 74 75 76 77 78
            decoration: new BoxDecoration(
              border: new Border(bottom: new BorderSide(color: theme.dividerColor))
            ),
            child: new InkWell(
              onTap: () {
                showTimePicker(
                  context: context,
                  initialTime: time
                )
79
                .then<Null>((TimeOfDay value) {
Hans Muller's avatar
Hans Muller committed
80 81 82 83 84 85
                  onChanged(new DateTime(date.year, date.month, date.day, value.hour, value.minute));
                });
              },
              child: new Row(
                children: <Widget>[
                  new Text('$time'),
86
                  const Icon(Icons.arrow_drop_down, color: Colors.black54),
Hans Muller's avatar
Hans Muller committed
87 88 89 90 91 92 93 94 95 96
                ]
              )
            )
          )
        ]
      )
    );
  }
}

97
class FullScreenDialogDemo extends StatefulWidget {
98
  @override
Hans Muller's avatar
Hans Muller committed
99 100 101 102
  FullScreenDialogDemoState createState() => new FullScreenDialogDemoState();
}

class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
103 104 105 106
  DateTime _fromDateTime = new DateTime.now();
  DateTime _toDateTime = new DateTime.now();
  bool _allDayValue = false;
  bool _saveNeeded = false;
Hans Muller's avatar
Hans Muller committed
107

108 109 110
  Future<bool> _onWillPop() async {
    if (!_saveNeeded)
      return true;
Hans Muller's avatar
Hans Muller committed
111 112

    final ThemeData theme = Theme.of(context);
113
    final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
Hans Muller's avatar
Hans Muller committed
114

115
    return await showDialog<bool>(
Hans Muller's avatar
Hans Muller committed
116
      context: context,
117
      child: new AlertDialog(
Hans Muller's avatar
Hans Muller committed
118 119 120 121 122 123
        content: new Text(
          'Discard new event?',
          style: dialogTextStyle
        ),
        actions: <Widget>[
          new FlatButton(
124
            child: const Text('CANCEL'),
125 126 127
            onPressed: () {
              Navigator.of(context).pop(false); // Pops the confirmation dialog but not the page.
            }
Hans Muller's avatar
Hans Muller committed
128 129
          ),
          new FlatButton(
130
            child: const Text('DISCARD'),
Hans Muller's avatar
Hans Muller committed
131
            onPressed: () {
132
              Navigator.of(context).pop(true); // Returning true to _onWillPop will pop again.
Hans Muller's avatar
Hans Muller committed
133 134 135 136
            }
          )
        ]
      )
137
    ) ?? false;
Hans Muller's avatar
Hans Muller committed
138 139
  }

140
  @override
Hans Muller's avatar
Hans Muller committed
141 142 143 144
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);

    return new Scaffold(
145
      appBar: new AppBar(
146
        title: const Text('New event'),
147
        actions: <Widget> [
Hans Muller's avatar
Hans Muller committed
148
          new FlatButton(
149
            child: new Text('SAVE', style: theme.textTheme.body1.copyWith(color: Colors.white)),
Hans Muller's avatar
Hans Muller committed
150 151 152 153 154 155
            onPressed: () {
              Navigator.pop(context, DismissDialogAction.save);
            }
          )
        ]
      ),
156 157 158 159 160 161 162 163 164 165 166 167
      body: new Form(
        onWillPop: _onWillPop,
        child: new ListView(
          padding: const EdgeInsets.all(16.0),
          children: <Widget>[
            new Container(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              decoration: new BoxDecoration(
                border: new Border(bottom: new BorderSide(color: theme.dividerColor))
              ),
              alignment: FractionalOffset.bottomLeft,
              child: new Text('Event name', style: theme.textTheme.display2)
168
            ),
169 170 171 172 173 174 175
            new Container(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              decoration: new BoxDecoration(
                border: new Border(bottom: new BorderSide(color: theme.dividerColor))
              ),
              alignment: FractionalOffset.bottomLeft,
              child: new Text('Location', style: theme.textTheme.title.copyWith(color: Colors.black54))
176
            ),
177 178 179 180 181 182 183 184 185 186 187 188 189 190
            new Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                new Text('From', style: theme.textTheme.caption),
                new DateTimeItem(
                  dateTime: _fromDateTime,
                  onChanged: (DateTime value) {
                    setState(() {
                      _fromDateTime = value;
                      _saveNeeded = true;
                    });
                  }
                )
              ]
191
            ),
192 193 194 195 196 197 198
            new Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                new Text('To', style: theme.textTheme.caption),
                new DateTimeItem(
                  dateTime: _toDateTime,
                  onChanged: (DateTime value) {
199
                    setState(() {
200
                      _toDateTime = value;
201 202 203 204
                      _saveNeeded = true;
                    });
                  }
                ),
xster's avatar
xster committed
205
                const Text('All-day'),
206
              ]
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
            ),
            new Container(
              decoration: new BoxDecoration(
                border: new Border(bottom: new BorderSide(color: theme.dividerColor))
              ),
              child: new Row(
                children: <Widget> [
                  new Checkbox(
                    value: _allDayValue,
                    onChanged: (bool value) {
                      setState(() {
                        _allDayValue = value;
                        _saveNeeded = true;
                      });
                    }
                  ),
xster's avatar
xster committed
223
                  const Text('All-day'),
224 225
                ]
              )
226
            )
227 228 229 230 231 232 233 234 235 236 237
          ]
          .map((Widget child) {
            return new Container(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              height: 96.0,
              child: child
            );
          })
          .toList()
        )
      ),
Hans Muller's avatar
Hans Muller committed
238 239 240
    );
  }
}