1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// 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/animation.dart';
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'material_button.dart';
import 'material.dart';
import 'theme.dart';
typedef Widget DialogBuilder(NavigatorState navigator);
/// A material design dialog
///
/// <https://www.google.com/design/spec/components/dialogs.html>
class Dialog extends StatelessComponent {
Dialog({
Key key,
this.title,
this.titlePadding,
this.content,
this.contentPadding,
this.actions
}) : super(key: key);
/// The (optional) title of the dialog is displayed in a large font at the top
/// of the dialog.
final Widget title;
// Padding around the title; uses material design default if none is supplied
// If there is no title, no padding will be provided
final EdgeDims titlePadding;
/// The (optional) content of the dialog is displayed in the center of the
/// dialog in a lighter font.
final Widget content;
// Padding around the content; uses material design default if none is supplied
final EdgeDims contentPadding;
/// The (optional) set of actions that are displayed at the bottom of the
/// dialog.
final List<Widget> actions;
Color _getColor(BuildContext context) {
switch (Theme.of(context).brightness) {
case ThemeBrightness.light:
return Colors.white;
case ThemeBrightness.dark:
return Colors.grey[800];
}
}
Widget build(BuildContext context) {
List<Widget> dialogBody = new List<Widget>();
if (title != null) {
EdgeDims padding = titlePadding;
if (padding == null)
padding = new EdgeDims.TRBL(24.0, 24.0, content == null ? 20.0 : 0.0, 24.0);
dialogBody.add(new Padding(
padding: padding,
child: new DefaultTextStyle(
style: Theme.of(context).text.title,
child: title
)
));
}
if (content != null) {
EdgeDims padding = contentPadding;
if (padding == null)
padding = const EdgeDims.TRBL(20.0, 24.0, 24.0, 24.0);
dialogBody.add(new Padding(
padding: padding,
child: new DefaultTextStyle(
style: Theme.of(context).text.subhead,
child: content
)
));
}
if (actions != null) {
dialogBody.add(new ButtonTheme(
color: ButtonColor.accent,
child: new Container(
child: new Row(actions,
justifyContent: FlexJustifyContent.end
)
)
));
}
return new Center(
child: new Container(
margin: new EdgeDims.symmetric(horizontal: 40.0, vertical: 24.0),
child: new ConstrainedBox(
constraints: new BoxConstraints(minWidth: 280.0),
child: new Material(
elevation: 24,
color: _getColor(context),
type: MaterialType.card,
child: new IntrinsicWidth(
child: new Block(dialogBody)
)
)
)
)
);
}
}
class _DialogRoute<T> extends PopupRoute<T> {
_DialogRoute({
Completer<T> completer,
this.child
}) : super(completer: completer);
final Widget child;
Duration get transitionDuration => const Duration(milliseconds: 150);
bool get barrierDismissable => true;
Color get barrierColor => Colors.black54;
Widget buildPage(BuildContext context, PerformanceView performance, PerformanceView forwardPerformance) {
return child;
}
Widget buildTransitions(BuildContext context, PerformanceView performance, PerformanceView forwardPerformance, Widget child) {
return new FadeTransition(
performance: performance,
opacity: new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.easeOut),
child: child
);
}
}
Future showDialog({ BuildContext context, Widget child }) {
Completer completer = new Completer();
Navigator.push(context, new _DialogRoute(completer: completer, child: child));
return completer.future;
}