@@ -7,13 +7,14 @@ import 'package:flutter/foundation.dart';
7
7
import 'package:flutter/widgets.dart' ;
8
8
9
9
import 'colors.dart' ;
10
+ import 'scrollbar.dart' ;
10
11
11
12
// TODO(abarth): These constants probably belong somewhere more general.
12
13
13
14
const TextStyle _kCupertinoDialogTitleStyle = const TextStyle (
14
15
fontFamily: '.SF UI Display' ,
15
16
inherit: false ,
16
- fontSize: 17.5 ,
17
+ fontSize: 17.5 ,
17
18
fontWeight: FontWeight .w600,
18
19
color: CupertinoColors .black,
19
20
height: 1.25 ,
@@ -23,7 +24,7 @@ const TextStyle _kCupertinoDialogTitleStyle = const TextStyle(
23
24
const TextStyle _kCupertinoDialogContentStyle = const TextStyle (
24
25
fontFamily: '.SF UI Text' ,
25
26
inherit: false ,
26
- fontSize: 12.4 ,
27
+ fontSize: 12.4 ,
27
28
fontWeight: FontWeight .w500,
28
29
color: CupertinoColors .black,
29
30
height: 1.35 ,
@@ -33,7 +34,7 @@ const TextStyle _kCupertinoDialogContentStyle = const TextStyle(
33
34
const TextStyle _kCupertinoDialogActionStyle = const TextStyle (
34
35
fontFamily: '.SF UI Text' ,
35
36
inherit: false ,
36
- fontSize: 16.8 ,
37
+ fontSize: 16.8 ,
37
38
fontWeight: FontWeight .w400,
38
39
color: CupertinoColors .activeBlue,
39
40
textBaseline: TextBaseline .alphabetic,
@@ -78,7 +79,7 @@ class CupertinoDialog extends StatelessWidget {
78
79
borderRadius: const BorderRadius .all (const Radius .circular (12.0 )),
79
80
child: new DecoratedBox (
80
81
// To get the effect, 2 white fills are needed. One blended with the
81
- // background before applying the blur and one overlayed on top of
82
+ // background before applying the blur and one overlaid on top of
82
83
// the blur.
83
84
decoration: _kCupertinoDialogBackFill,
84
85
child: new BackdropFilter (
@@ -116,6 +117,7 @@ class CupertinoAlertDialog extends StatelessWidget {
116
117
this .title,
117
118
this .content,
118
119
this .actions,
120
+ this .scrollController,
119
121
}) : super (key: key);
120
122
121
123
/// The (optional) title of the dialog is displayed in a large font at the top
@@ -136,15 +138,24 @@ class CupertinoAlertDialog extends StatelessWidget {
136
138
/// Typically this is a list of [CupertinoDialogAction] widgets.
137
139
final List <Widget > actions;
138
140
141
+ /// A scroll controller that can be used to control the scrolling of the message
142
+ /// in the dialog.
143
+ ///
144
+ /// Defaults to null, and is typically not needed, since most alert messages are short.
145
+ final ScrollController scrollController;
146
+
139
147
@override
140
148
Widget build (BuildContext context) {
141
- final List <Widget > children = < Widget > [];
142
-
143
- children.add (const SizedBox (height: 18.0 ));
144
-
149
+ const double edgePadding = 20.0 ;
150
+ final List <Widget > titleContentGroup = < Widget > [];
145
151
if (title != null ) {
146
- children.add (new Padding (
147
- padding: const EdgeInsets .only (left: 20.0 , right: 20.0 , bottom: 2.0 ),
152
+ titleContentGroup.add (new Padding (
153
+ padding: new EdgeInsets .only (
154
+ left: edgePadding,
155
+ right: edgePadding,
156
+ bottom: content == null ? edgePadding : 1.0 ,
157
+ top: edgePadding,
158
+ ),
148
159
child: new DefaultTextStyle (
149
160
style: _kCupertinoDialogTitleStyle,
150
161
textAlign: TextAlign .center,
@@ -154,38 +165,57 @@ class CupertinoAlertDialog extends StatelessWidget {
154
165
}
155
166
156
167
if (content != null ) {
157
- children.add (new Flexible (
158
- fit: FlexFit .loose,
159
- child: new Padding (
160
- padding: const EdgeInsets .symmetric (horizontal: 20.0 ),
168
+ titleContentGroup.add (
169
+ new Padding (
170
+ padding: new EdgeInsets .only (
171
+ left: edgePadding,
172
+ right: edgePadding,
173
+ bottom: edgePadding,
174
+ top: title == null ? edgePadding : 1.0 ,
175
+ ),
161
176
child: new DefaultTextStyle (
162
177
style: _kCupertinoDialogContentStyle,
163
178
textAlign: TextAlign .center,
164
179
child: content,
165
180
),
166
181
),
167
- )) ;
182
+ );
168
183
}
169
184
170
- children.add (const SizedBox (height: 22.0 ));
185
+ final List <Widget > children = < Widget > [];
186
+ if (titleContentGroup.isNotEmpty) {
187
+ children.add (
188
+ new Flexible (
189
+ child: new CupertinoScrollbar (
190
+ child: new ListView (
191
+ controller: scrollController,
192
+ shrinkWrap: true ,
193
+ children: titleContentGroup,
194
+ ),
195
+ ),
196
+ ),
197
+ );
198
+ }
171
199
172
200
if (actions != null ) {
173
201
children.add (new _CupertinoButtonBar (
174
202
children: actions,
175
203
));
176
204
}
177
205
178
- return new CupertinoDialog (
179
- child: new Column (
180
- mainAxisSize: MainAxisSize .min,
181
- crossAxisAlignment: CrossAxisAlignment .stretch,
182
- children: children,
206
+ return new Padding (
207
+ padding: const EdgeInsets .symmetric (vertical: edgePadding),
208
+ child: new CupertinoDialog (
209
+ child: new Column (
210
+ mainAxisSize: MainAxisSize .min,
211
+ crossAxisAlignment: CrossAxisAlignment .stretch,
212
+ children: children,
213
+ ),
183
214
),
184
215
);
185
216
}
186
217
}
187
218
188
-
189
219
/// A button typically used in a [CupertinoAlertDialog] .
190
220
///
191
221
/// See also:
@@ -208,7 +238,7 @@ class CupertinoDialogAction extends StatelessWidget {
208
238
209
239
/// Set to true if button is the default choice in the dialog.
210
240
///
211
- /// Default buttons are bolded .
241
+ /// Default buttons are bold .
212
242
final bool isDefaultAction;
213
243
214
244
/// Whether this action destroys an object.
@@ -229,22 +259,29 @@ class CupertinoDialogAction extends StatelessWidget {
229
259
Widget build (BuildContext context) {
230
260
TextStyle style = _kCupertinoDialogActionStyle;
231
261
232
- if (isDefaultAction)
262
+ if (isDefaultAction) {
233
263
style = style.copyWith (fontWeight: FontWeight .w600);
264
+ }
234
265
235
- if (isDestructiveAction)
266
+ if (isDestructiveAction) {
236
267
style = style.copyWith (color: CupertinoColors .destructiveRed);
268
+ }
237
269
238
- if (! enabled)
270
+ if (! enabled) {
239
271
style = style.copyWith (color: style.color.withOpacity (0.5 ));
272
+ }
240
273
274
+ final double textScaleFactor = MediaQuery .of (context, nullOk: true )? .textScaleFactor ?? 1.0 ;
241
275
return new GestureDetector (
242
276
onTap: onPressed,
243
277
behavior: HitTestBehavior .opaque,
244
- child: new Center (
278
+ child: new Container (
279
+ alignment: Alignment .center,
280
+ padding: new EdgeInsets .all (10.0 * textScaleFactor),
245
281
child: new DefaultTextStyle (
246
282
style: style,
247
283
child: child,
284
+ textAlign: TextAlign .center,
248
285
),
249
286
),
250
287
);
@@ -271,18 +308,22 @@ class _CupertinoButtonBar extends StatelessWidget {
271
308
272
309
for (Widget child in children) {
273
310
// TODO(abarth): Listen for the buttons being highlighted.
311
+ // TODO(gspencer): These buttons don't lay out in the same way as iOS.
312
+ // When they get wide, they should stack vertically instead of in a row.
313
+ // When they get really big, the vertically-stacked buttons should scroll
314
+ // (separately from the top message).
274
315
buttons.add (new Expanded (child: child));
275
316
}
276
317
277
318
return new CustomPaint (
278
319
painter: new _CupertinoButtonBarPainter (children.length),
279
- child: new SizedBox (
280
- height : _kButtonBarHeight ,
281
- child: new Row (
282
- crossAxisAlignment : CrossAxisAlignment .stretch ,
283
- children: buttons
320
+ child: new UnconstrainedBox (
321
+ constrainedAxis : Axis .horizontal ,
322
+ child: new ConstrainedBox (
323
+ constraints : const BoxConstraints (minHeight : _kButtonBarHeight) ,
324
+ child : new Row ( children: buttons),
284
325
),
285
- )
326
+ ),
286
327
);
287
328
}
288
329
}
0 commit comments